Monday, January 28, 2013

Binary Huffman Code in C++

Huffman code is an optimal code for the given source (probability distribution), which assigns small length codes to high frequent symbols. For more information click here.

GenHuffmanCode.cpp

#include "MinPriorityQueue.cpp"

using namespace std;

class Node {
public:
    string name;
    int f;
    Node *left, *right;
    string code;

    Node() {
        name = "";
        code = "";
        f = INT_MAX;
        left = right = 0;
    }

    Node(int ff, string n = "") {
        name = n;
        f = ff;
        left = right = 0;
        code = "";
    }

    ~Node() {
        delete left;
        delete right;
    }

    bool operator<(Node &param) {
        return f < param.f;
    }

    bool operator>(Node &param) {
        return f > param.f;
    }

    bool operator==(Node &param) {
        return f == param.f;
    }

    static void display(Node*, bool);
    static void encode(Node*);

    friend ostream& operator <<(ostream&, Node&);
};

void Node::display(Node* node, bool leavesOnly = 1) {
    if (node == 0) {
        return;
    }
    display(node->left, leavesOnly);
    if (leavesOnly) {
        if (node->left == 0 && node->right == 0) {
            cout << *node << ", ";
        }
    } else {
        cout << *node << ", ";
    }
    display(node->right, leavesOnly);
}

void Node::encode(Node* node) {
    if (node == 0) {
        return;
    }
    if (node->left != 0) {
        node->left->code = node->code + "0";
    }
    if (node->right != 0) {
        node->right->code = node->code + "1";
    }
    encode(node->left);
    encode(node->right);
}

ostream& operator <<(ostream &out, Node &node) {
    out << node.name << "(" << node.f << ")" << ":" << node.code;
    return out;
}

void HuffmanCode(int *freqs, string* names, int length) {
    Q<Node> *q = new Q<Node > (length);
    for (int i = 0; i < length; i++) {
        q->insert(new Node(freqs[i], names[i]));
    }

    for (int i = 0; i < length - 1; i++) {
        Node *x = q->extractMin();
        Node *y = q->extractMin();
        Node *z = new Node(x->f + y->f, x->name + y->name);
        z->left = x;
        z->right = y;
        q->insert(z);
    }
    Node *root = q->extractMin();
    cout << "Full tree (inorder):\n";
    Node::display(root, 0);
    cout << "\nHuffman Code:\n";
    Node::encode(root);
    Node::display(root);
}

int main(int argc, char** argv) {
    int freqs[] = {45, 13, 12, 16, 9, 5};
    string names[] = {"a", "b", "c", "d", "e", "f"};
    HuffmanCode(freqs, names, 6);
    return 0;
}

Output

Full tree (inorder):
a(45):, acbfed(100):, c(12):, cb(25):, b(13):, cbfed(55):, f(5):, fe(14):, e(9):, fed(30):, d(16):, 
Huffman Code:
a(45):0, c(12):100, b(13):101, f(5):1100, e(9):1101, d(16):111, 

Minimum Priority Queue Implemented Using Min-Heap in C++

MinPriorityQueue.h

#ifndef MINPRIORITYQUEUE_H
#define MINPRIORITYQUEUE_H

template<class T> class Q {
    int array_size, heap_size;
    T** A; // pointer for the array    

public:
    Q(int s);
    ~Q();
    bool isEmpty();
    bool isFull();
    T** getArray();
    int getArraySize();
    T* minimum();
    T* extractMin();
    bool insert(T*);

private:
    int left(int i);
    int right(int i);
    int parent(int i);
    void decreaseKey(int, T*);
    void minHeapify(int);
};

#endif /* MINPRIORITYQUEUE_H */

MinPriorityQueue.cpp

#include <cstdlib>
#include <iostream>
#include "MinPriorityQueue.h"

using namespace std;

template<class T> Q<T>::Q(int s) {
    array_size = s;
    heap_size = -1;
    A = new T*[s];
}

template<class T> Q<T>::~Q() {
    delete A;
}

template<class T> bool Q<T>::isEmpty() {
    return heap_size < 0;
}

template<class T> bool Q<T>::isFull() {
    return heap_size >= array_size - 1;
}

template<class T> T** Q<T>::getArray() {
    return A;
}

template<class T> int Q<T>::getArraySize() {
    return array_size;
}

template<class T> T* Q<T>::minimum() {
    return A[0];
}

template<class T> int Q<T>::left(int i) {
    return 2 * (i + 1) - 1;
}

template<class T> int Q<T>::right(int i) {
    return 2 * (i + 1);
}

template<class T> int Q<T>::parent(int i) {
    return max((i + 1) / 2 - 1, 0);
}

template<class T> T* Q<T>::extractMin() {
    if (isEmpty()) {
        cout << "Underflow...\n";
        T* t;
        return t;
    } else {
        T* min = A[0];
        A[0] = A[heap_size];
        heap_size--;
        minHeapify(0);
        return min;
    }
}

template<class T> void Q<T>::minHeapify(int i) {
    int l = left(i);
    int r = right(i);
    int smallest = i;
    if (l <= heap_size && ((*(A[l])) < (*(A[i])))) {
        smallest = l;
    }
    if (r <= heap_size && ((*(A[r])) < (*(A[smallest])))) {
        smallest = r;
    }
    if (smallest != i) {
        T* t = A[i];
        A[i] = A[smallest];
        A[smallest] = t;
        minHeapify(smallest);
    }
}

template<class T> bool Q<T>::insert(T* key) {
    if (isFull()) {
        cout << "Overflow...\n";
        return false;
    } else {
        heap_size++;
        decreaseKey(heap_size, key);
        return true;
    }
}

template<class T> void Q<T>::decreaseKey(int i, T* key) {
    A[i] = key;
    while ((i > 0) && ((*(A[parent(i)])) > (*(A[i])))) {
        T* t = A[i];
        A[i] = A[parent(i)];
        A[parent(i)] = t;
        i = parent(i);
    }
}

TestMinPriorityQueue.cpp

#include "MinPriorityQueue.cpp"

using namespace std;

void testMinPQ() {
    Q<int> *q = new Q<int>(10);
    int x[] = {10, 5, 8, 15, 4, 20, 28, 33, 11, 3};
    for (int i = 0; i < 10; i++) {
        q->insert(&x[i]);
    }
    for (int i = 0; i < 10; i++) {
        cout << (*q->extractMin()) << ", ";
    }
}

int main(int argc, char** argv) {
    testMinPQ();
    return 0;
}

Output

3, 4, 5, 8, 10, 11, 15, 20, 28, 33,



Wednesday, January 9, 2013

Lowest Common Multiplier and Greatest Common Divisor in Python

Lowest Common Multiplier (LCM) and Greatest Common Divisor (GCD) can be found for any list of numbers by this code. 
LCM x GCD = FACT(x1,x2,...xn)
Here, FACT(x1,x2,...xn) is the multiplication of the input arguments x1 to xn. I used the above equation to find the GCD by calculating LCM first. However, you can calculate GCD directly using Euclid's algorithm.

Code

def lcm(x,y):
    tmp=x
    while (tmp%y)!=0:
        tmp+=x
    return tmp

def lcmm(*args):
    return reduce(lcm,args)

def fact(args):
    if len(args) == 0:
        return 1
    else:
        return args[0] * fact(args[1:])

def gcd(args):
    return fact(args)/lcmm(*args)

args=range(1,11)
print args
print 'LCM:', lcmm(*args)
print 'GCD:', gcd(args)

Euclid's Algorithm

def gcd(a, b):
    while b:      
        a, b = b, a % b
    return a

Question

Find the sequence of numbers whose remainder is one less than its divisor?
Eg. Consider N, N mod x = x - 1 for x in list 1 - 20. Find the sequence of N?

Ans. Find the LCM of list 1 - 20, then N = k * LCM - 1, where k is an integer.

Friday, May 18, 2012

Pseudo Random Sequence Generator in Verilog


Pseudo Random Sequence is widely used in spread spectrum communication, to spread and de-spread the information sequence. The following diagram shows a PN sequence generator which has 3 memory elements, leads to processing gain 7 (2^3 - 1). According to the diagram, if the initial state is all zero, then the sequence will also be all zeros which is not usable.




Behavioural Model

module PNSeqGen(
    input clk, reset,
    output s3
    );
reg s1, s2, s3;
wire s0;
// MODULO 2 ADDITION
assign s0 = s1 ^ s3;
// STATE MACHINE
always @ (posedge clk or reset) begin
// INITIAL STATE SHOULDN'T BE 000 => 100
if(reset) begin
s1 <= 1;
s2 <= 0;
s3 <= 0;
end else begin
s1 <= s0;
s2 <= s1;
s3 <= s2;
end
end
endmodule

Test Bench

`timescale 1ns / 1ps
module Test_PNSeqGen;
// Inputs
reg clk;
reg reset;
// Outputs
wire s3;
// Instantiate the Unit Under Test (UUT)
PNSeqGen uut (
.clk(clk), 
.reset(reset), 
.s3(s3)
);
initial begin
// Initialize Inputs
clk = 0;
reset = 0;
// Wait 100 ns for global reset to finish
#100;
// Add stimulus here
#10 reset = 1;
#10 reset = 0;
#200 $finish;
end
always begin
#5 clk = ~clk;
end
// PRINT SEQUENCE
always @ (posedge clk) $write("%b",s3);      
endmodule

Output

001110100111010011101

Tuesday, May 8, 2012

4 Bit Priority Encoder in Verilog


Priority Encoder is an encoder circuit that includes a priority function. The operation is such that if two or more inputs are equal to 1 at the same time, the input having the highest priority will take precedence. 
Here, the priority decreases from right to left in the input. D[3] has the highest priority. V indicate the validity of the input (atleast one input should be 1) and the Y gives the output.(01 means 1, 10 means 2 like that...)


















Behavioural Model : 4 Bit Priority Encoder

module PriorityEncoder_4Bit(
    input [0:3] D,
    output [1:0] Y,
    output V
    );
reg [1:0] Y;
reg V;
always @(D)
begin
Y[1] <= D[2] | D[3];
Y[0] <= D[3] | D[1] & ~D[2];
V = D[0] | D[1] | D[2] | D[3];
end
endmodule

Test Bench : 4 Bit Priority Encoder

module PriorityEncoder_4Bit_Test;
// Inputs
reg [3:0] D;
// Outputs
wire [1:0] Y;
wire V;
// Instantiate the Unit Under Test (UUT)
PriorityEncoder_4Bit uut (
.D(D), 
.Y(Y), 
.V(V)
);
initial begin
// Initialize Inputs
D = 0;
// Wait 100 ns for global reset to finish
#100;        
// Add stimulus here
#10 D = 4'b0000;
#10 D = 4'b1000;
#10 D = 4'b0100;
#10 D = 4'b0010;
#10 D = 4'b0001;
#10 D = 4'b1010;
#10 D = 4'b1111;
end
initial begin
$monitor("time=",$time,, "D=%b : Y=%b V=%b",D,Y,V);
end      
endmodule

Simulation Results

time= 000, D=0000 : Y=00 V=0
time= 120, D=1000 : Y=00 V=1
time= 130, D=0100 : Y=01 V=1
time= 140, D=0010 : Y=10 V=1
time= 150, D=0001 : Y=11 V=1
time= 160, D=1010 : Y=10 V=1
time= 170, D=1111 : Y=11 V=1

Wednesday, February 29, 2012

Camera Simulation on 3D Data

I used third party ply_read() Matlab function to read the 3D data. I simulate the camera by changing the camera position and rotation in predefined trajectories.

Matlab Code

% USE THIRD PARTY FUNCTION TO READ 3D DATA
[Tri, Pts] = ply_read('bunny.ply', 'tri');
[elements, var] = ply_read('bunny.ply');
conf = elements.vertex.confidence;

c = size(Pts, 2); % NO OF VERTICES
f = 0.05; % F = 50mm
cam_pos = [0; 0; -0.5];
theta_x = 0; theta_y = 0; theta_z = 0;  % CAMERA ROTATION PARAMETERS
video_im = uint8(zeros(301, 301, 1, 301)); % OUTPUT IMAGE FRAMES

% MOVE CAMERA TOWARDS OBJECT IN SINE TRAJECTORY
dist1=-0.5 + sin(linspace(0,pi,100))/10; 
dist4=-0.5 - sin(linspace(0,pi,200));
% ROTATE 360 DEGREES WITH RESPECT TO Y AXIS
dist2=linspace(0,2*pi,200);
% ROTATE 360 DEGREES WITH RESPECT TO X AXIS
dist3=linspace(0,2*pi,200);
% CONCATINATED LIST
dist=[dist1,dist2,dist3];

for i = 1 : length(dist)
% CHANGE TRANSFORMATION PARAMETERS
    if(i <= length(dist1))
        cam_pos=[0;0;dist(i)];
    elseif(i <= length(dist2) + length(dist1))
        theta_y = dist(i);
    else
        theta_x = dist(i);
        theta_y = dist(i);
        theta_z = dist(i);
        cam_pos=[0;0;dist4(i-300)];
    end
% CAMERA TRANSOFRMATION MATRIX (ROTATION)
    Rx = [1 0 0; 0 cos(theta_x) -1*sin(theta_x); 0 sin(theta_x) cos(theta_x)];
    Ry = [cos(theta_y) 0 sin(theta_y); 0 1 0; -1*sin(theta_y) 0 cos(theta_y)];
    Rz = [cos(theta_z) -1*sin(theta_z) 0; sin(theta_z) cos(theta_z) 0; 0 0 1];

    eff_obj_data = Pts - repmat(cam_pos, 1, c);
    D = Rx * Ry * Rz * (eff_obj_data);
    
% APPLY TRANSFORMATION
    P = [f*eye(3) zeros(3,1)]; % CAMERA MATRIX
    im = P*[D; f*ones(1, c)];
    scaled_im = im(1 : 2, :);
    % SCALING THE IMAGE TO THE RANGE
    scaled_im(1, :) = (im(1, :)  - min(im(1, :)))./abs(im(3, :)).*600;
    scaled_im(2, :) = (im(2, :)  - min(im(2, :)))./abs(im(3, :)).*600;
    scaled_im = ceil(scaled_im) + 1;

% INTENSITY MAPPING
    im_out = zeros(301, 301);
    for j = 1 : c
        if(scaled_im(2, j) < 302 && scaled_im(1, j) < 301)
            im_out(302 - scaled_im(2, j), scaled_im(1, j)) = conf(j);
        end
    end
% COLLECTING FRAMES
video_im(:, :, :, i) = uint8(im_out.*200);
end

mov = immovie(video_im, gray);
movie2avi(mov, 'out.avi'); % SAVE VIDEO
implay(mov);

Output


4 Bit Carry Look Ahead Adder in Verilog


DataFlow Model : 4 Bit CLA

module CLA_4bit(
    output [3:0] S,
    output Cout,PG,GG,
    input [3:0] A,B,
    input Cin
    );
    wire [3:0] G,P,C;

    assign G = A & B; //Generate
    assign P = A ^ B; //Propagate
    assign C[0] = Cin;
    assign C[1] = G[0] | (P[0] & C[0]);
    assign C[2] = G[1] | (P[1] & G[0]) | (P[1] & P[0] & C[0]);
    assign C[3] = G[2] | (P[2] & G[1]) | (P[2] & P[1] & G[0]) |             (P[2] & P[1] & P[0] & C[0]);
    assign Cout = G[3] | (P[3] & G[2]) | (P[3] & P[2] & G[1]) | (P[3] & P[2] & P[1] & G[0]) |(P[3] & P[2] & P[1] & P[0] & C[0]);
    assign S = P ^ C;
    
    assign PG = P[3] & P[2] & P[1] & P[0];
    assign GG = G[3] | (P[3] & G[2]) | (P[3] & P[2] & G[1]) | (P[3] & P[2] & P[1] & G[0]);
endmodule

Test Bench : 4 Bit CLA

module Test_CLA_4bit;
    // Inputs
    reg [3:0] A;
    reg [3:0] B;
    reg Cin;

    // Outputs
    wire [3:0] S;
    wire Cout;
    wire PG;
    wire GG;

    // Instantiate the Unit Under Test (UUT)
    CLA_4bit uut (
    .S(S), 
    .Cout(Cout), 
    .PG(PG), 
    .GG(GG), 
    .A(A), 
    .B(B), 
    .Cin(Cin)
    );

    initial begin
    // Initialize Inputs
    A = 0; B = 0; Cin = 0;
    // Wait 100 ns for global reset to finish
    #100;
        
    // Add stimulus here
    A=4'b0001;B=4'b0000;Cin=1'b0;
    #10 A=4'b100;B=4'b0011;Cin=1'b0;
    #10 A=4'b1101;B=4'b1010;Cin=1'b1;
    #10 A=4'b1110;B=4'b1001;Cin=1'b0;
    #10 A=4'b1111;B=4'b1010;Cin=1'b0;
    end

    initial begin
$monitor("time=",$time,, "A=%b B=%b Cin=%b : Sum=%b Cout=%b PG=%b GG=%b",A,B,Cin,S,Cout,PG,GG);
    end      
endmodule

Simulation Results

time = 0 A=0000 B=0000 Cin=0 : Sum=0000 Cout=0 PG=0 GG=0
time = 100 A=0001 B=0000 Cin=0 : Sum=0001 Cout=0 PG=0 GG=0
time = 110 A=0100 B=0011 Cin=0 : Sum=0111 Cout=0 PG=0 GG=0
time = 120 A=1101 B=1010 Cin=1 : Sum=1000 Cout=1 PG=0 GG=1
time = 130 A=1110 B=1001 Cin=0 : Sum=0111 Cout=1 PG=0 GG=1
time = 140 A=1111 B=1010 Cin=0 : Sum=1001 Cout=1 PG=0 GG=1

Thursday, February 16, 2012

4 Bit Ripple Carry Adder in Verilog


Structural Model : Half Adder

module half_adder(
    output S,C,
input A,B
    );
xor(S,A,B);
and(C,A,B);

endmodule

Structural Model : Full Adder

module full_adder(
    output S,Cout,
    input A,B,Cin
    );
wire s1,c1,c2;
half_adder HA1(s1,c1,A,B);
half_adder HA2(S,c2,s1,Cin);
or OG1(Cout,c1,c2);

endmodule

Structural Model : 4 Bit Ripple Carry Adder

module ripple_adder_4bit(
    output [3:0] Sum,
    output Cout,
    input [3:0] A,B,
    input Cin
    );
wire c1,c2,c3;
full_adder FA1(Sum[0],c1,A[0],B[0],Cin),
FA2(Sum[1],c2,A[1],B[1],c1),
FA3(Sum[2],c3,A[2],B[2],c2),
FA4(Sum[3],Cout,A[3],B[3],c3);

endmodule

Test Bench : 4 Bit Ripple Carry Adder

module test_ripple_adder_4bit;
// Inputs
reg [3:0] A;
reg [3:0] B;
reg Cin;
// Outputs
wire [3:0] Sum;
wire Cout;
// Instantiate the Unit Under Test (UUT)
ripple_adder_4bit uut (
.Sum(Sum), 
.Cout(Cout), 
.A(A), 
.B(B), 
.Cin(Cin)
);
initial begin
// Initialize Inputs
A = 0;
B = 0;
Cin = 0;
// Wait 100 ns for global reset to finish
#100;        
// Add stimulus here
A=4'b0001;B=4'b0000;Cin=1'b0;
#10 A=4'b1010;B=4'b0011;Cin=1'b0;
#10 A=4'b1101;B=4'b1010;Cin=1'b1;
end
initial begin
$monitor("time=",$time,, "A=%b B=%b Cin=%b : Sum=%b Cout=%b",A,B,Cin,Sum,Cout);
end
      
endmodule

Saturday, February 11, 2012

Graph Cut Segmentation

Here, I've used the Planar Graph Cut library on Prof. Olga Veksler's website to develop this program to segment an image using graph cuts.

OpenCV Code

#include "stdafx.h"
#include "windows.h"
#include "CutSegment.h" //include PlanarCut
#include <iostream>
#include <stdio.h>
#include <string>
#include <fstream>
#include <sstream>
#include <stdlib.h>

using namespace std;

unsigned char *loadSimplePPM(int &w, int &h, const string &filename) {
  char line[1000];
  int depth = 0;
  unsigned char *rgb = 0;
  long lastpos;
  FILE *fh = fopen(filename.c_str(), "rb");  
  w = 0, h = 0;
  fgets(line, 1000, fh);
  if (strcmp(line, "P6\n")) {
    cerr << filename << " ist keine PPM-Datei\n";
    return false;
  }
  while (!feof(fh)) {
    lastpos = ftell(fh);    
    fgets(line, 1000, fh);
    if (line[0] == '#') {
    } else if (!w) {
      if (sscanf(line, "%d %d", &w, &h) < 2) {
cerr << "Fehler beim Auslesen der Datei " << filename;
cerr << " Breite und Hoehe des Bildes erwartet\n";
return 0;
      }
    } else if (!depth) {
      if (sscanf(line, "%d", &depth) < 1) {
cerr << "Fehler beim Auslesen der Datei " << filename;
cerr << " Farbtiefe erwartet\n";
return 0;
      }
    } else {
      rgb = new unsigned char[w*h*3];
      fseek(fh, lastpos, SEEK_SET);
      fread(rgb, 1, w*h*3, fh);
      break;
    }  
  }
  fclose(fh);
  return rgb;
}

bool saveSimplePPM(unsigned char *rgb, int w, int h, const string &filename) {
  ofstream fos(filename.c_str(), ios_base::binary);
  ostringstream ost;
  string s;
  if (!fos)
    return false;
  fos << "P6" << endl;
  ost << w << " " << h << endl;
  fos << ost.str();
  fos << "255" << endl;
  fos.write((const char*)rgb, w*h*3);
  fos.close();  
  return true;
}

unsigned char *RGBDataToGrey(unsigned char *rgb, int w, int h) {  
  unsigned char *pic = new unsigned char[w*h];
  int i;
  for (i=0; i<w*h; i++)
    pic[i] = rgb[i*3];
  return pic;
}

unsigned char *GreyDataToRGB(unsigned char *pic, int w, int h) {
  unsigned char *rgb = new unsigned char[w*h*3];
  int i;
  for (i=0; i<w*h; i++)
    rgb[i*3] = rgb[i*3+1] = rgb[i*3+2] = pic[i];  
  return rgb;
}

unsigned char *SegMaskAndGreyDataToRGB(CutPlanar::ELabel *mask, unsigned char *pic, int w, int h) {
  unsigned char *rgb = new unsigned char[w*h*3];
  int i;
  for (i=0; i<w*h; i++) {
    rgb[i*3] = (mask[i]==CutPlanar::LABEL_SINK) ? (unsigned char)(pic[i*3] / 255.f * 200.f) : 255;
    rgb[i*3+1] = (unsigned char)(pic[i*3+1] / 255.f * 200.f);
    rgb[i*3+2] = (mask[i]==CutPlanar::LABEL_SINK) ? 255 : (unsigned char)(pic[i*3+2] / 255.f * 200.f);
  }  
  return rgb;
}

unsigned char *getSegmentationInfo(unsigned char *rgb, int w, int h) {
  unsigned char *seginfo = new unsigned char[w*h];
  unsigned char r, g, b;
  int i;
  for (i=0; i<w*h; i++) {
    r = rgb[i*3];
    g = rgb[i*3+1];
    b = rgb[i*3+2];
    if (r >= 240 && g <= 10  && b <= 10) {
      seginfo[i] = 1;
    } else if (r <= 10 && g <= 10 && b >= 240) {
      seginfo[i] = 2;
    } else {
      seginfo[i] = 0;
    };
  }    
  return seginfo;
}

int _tmain(int argc, _TCHAR* argv[]) {
  CutSegment *sc;
  int w, h;
  uchar *seg, *rgb, *rgbNew, *grey;
  CutPlanar::ELabel *mask;
  size_t pos;
  string picname, segname, basename, suffix;
  char tmp[4096]; //just needed for windows character conversion  
  picname = "F:/PlanarCut/examples/pics/walk1.ppm";
  pos = picname.rfind(".ppm");
  if (pos == string::npos) {
    cerr << "testCutGrid only accepts .ppm images\n";
    return -1;
  }
  suffix = picname.substr(pos);
  basename = picname.substr(0, pos); 
  picname = basename + suffix;
  segname = basename + "seg" + suffix; 
  //load the prelabeled image from file
  rgb = loadSimplePPM(w, h, segname);
  seg = getSegmentationInfo(rgb, w, h);
  delete [] rgb;
  //load the image to be segmented from file
  rgb = loadSimplePPM(w, h, picname);
  grey = RGBDataToGrey(rgb, w, h);
  cout << "Image width: " << w << " and image height " << h << endl;
  //perform segmentation task
  sc = new CutSegment(w, h);
  sc->setImageData(grey);
  sc->setSourceSink(seg,1,2);
  cout << "Cut: " << sc->segment() << "\n";
  mask = new CutPlanar::ELabel[w*h];
  sc->getLabels(mask);
  delete sc;
  //read out segmentation result and save to disk
  rgbNew = SegMaskAndGreyDataToRGB(mask, rgb, w, h);
  saveSimplePPM(rgbNew, w, h, string("segresult.ppm"));
  //release memory
  delete [] grey;
  delete [] rgb;
  delete [] rgbNew;
  delete [] seg;
  delete [] mask;
  return 0;
}

Input

Image to be Segmented
Pre-labeled Image

Output

Segmentation Result