示例#1
0
文件: bic.c 项目: tiagojc/IBTSFIF
void ComputeFrequencyProperty(Image *img, Property *ppt)
{ 
  long x, y, p, q;
  int i, border;
  AdjRel *A;
  Pixel v;
  
  A = Circular(1.0);
  
  for(y=0; y<img->nrows; y++){
    for(x=0; x<img->ncols; x++){
      p = x + img->tbrow[y];
      border=false;
      for (i=1; i < A->n; i++){
	v.x = x + A->dx[i];
	v.y = y + A->dy[i];
	if (ValidPixel(img,v.x,v.y)){
	  q = v.x + img->tbrow[v.y];
	  if(ppt[p].color!=ppt[q].color){ 
	    border=true;
	    break;
	  }
	}
      }
      if(border==false) 
	ppt[p].frequency=LOW;
      else 
        ppt[p].frequency=HIGH;
    }
  }
  DestroyAdjRel(&A);
}
示例#2
0
文件: acc.c 项目: rafaelalmeida/poc
void ComputeFrequencyProperty(Image *img, ACCProperty *ppt)
{ 
  ulong x, y, p, q;
  uchar d, r;
  AdjRel *A;
  Pixel v;
  int i;

  for (p=0; p<img->nrows*img->ncols; p++)
    for (d=0; d<4; d++)
      ppt[p].frequency[d] = 0;

  A = Circular(1.0);
  for(y=0; y<img->nrows; y++)
    for(x=0; x<img->ncols; x++){
      p = x + img->tbrow[y];
      for(r=1,d=0; r<=7; r+=2,d++)
        for (i=1; i < A->n; i++){
          v.x = x + r * A->dx[i]; 
          v.y = y + r * A->dy[i];
          if (ValidPixel(img,v.x,v.y)){
            q = v.x + img->tbrow[v.y];
            if(ppt[p].color == ppt[q].color)
	      ppt[p].frequency[d]++;
	  }
        }
    }
  DestroyAdjRel(&A);
}
示例#3
0
CImage *CROI(CImage *cimg, int xl, int yl, int xr, int yr)
{
  CImage *croi=NULL;
  int i;

  if (ValidPixel(cimg->C[0],xl,yl)&&ValidPixel(cimg->C[0],xr,yr)&&
      (xl <= xr)&&(yl <= yr)) {
    croi = (CImage *) calloc(1,sizeof(CImage));
    if (croi == NULL){
      Error(MSG1,"CreateCImage");
    }
    for (i=0; i<3; i++)
      croi->C[i] = ROI(cimg->C[i], xl, yl, xr, yr);
  }
  return (croi);
}
示例#4
0
文件: cimage.c 项目: afalcao/ift-demo
CImage *DrawLabeledRegions(Image *img, Image *label){
  CImage *border=CreateCImage(img->ncols,img->nrows);
  int x,y,k,p,q,u,v;
  AdjRel *A;

  A = Circular(1.0);
  for(y=0;y<img->nrows;y++){
    for(x=0;x<img->ncols;x++){
      p = x + img->tbrow[y];
      border->C[0]->val[p]=
	border->C[1]->val[p]=border->C[2]->val[p]=img->val[p];

      for(k=1;k<A->n;k++){
	u = x+A->dx[k];
	v = y+A->dy[k];
	if(ValidPixel(img,u,v)){
	  q= u + img->tbrow[v];
	  if (label->val[p] != label->val[q]){
	    border->C[0]->val[p]=255;
	    border->C[1]->val[p]=0;
	    border->C[2]->val[p]=0;
	    break;
	  }
	}
      }
    }
  }
  DestroyAdjRel(&A);

  return(border);
}
示例#5
0
Set *ForestRemoval(ImageForest *fst, Set *Rm, AdjRel *A)
{
  int  i, p, q, n = fst->cost->ncols*fst->cost->nrows;
  Image *cost=fst->cost,*pred=fst->pred,*root=fst->root;
  Pixel u,v;
  Set  *Frontier=NULL, *aux=NULL;
  BMap *RemRoot = BMapNew(n), *inFrontier = BMapNew(n);  
  int  *RemNode=AllocIntArray(n),first=0,last=0;

  /* Mark all removal roots, whose trees will be removed, reinitialize
  cost and predecessor values of those roots, and insert them in
  RemNode, in order to reinitialize the cost and predecessor values of
  the remaining nodes of the removed trees. */

  aux = Rm;
  while (aux != NULL) { 
    p = root->val[aux->elem]; // get a removal root p 
    if (_fast_BMapGet(RemRoot,p)==0){ // p is not in RemRoot
      cost->val[p] = INT_MAX;  pred->val[p] = NIL;
      RemNode[last]=p; last++;
      _fast_BMapSet1(RemRoot,p);
    }
    aux = aux->next;
  }

  /* Forest removal: reinitialize nodes of the removed trees and
     create frontier set for the next DIFT. */

  while (first != last) {
    p = RemNode[first]; first++;
    u.x = p % cost->ncols; 
    u.y = p / cost->ncols; 
    for (i=1; i < A->n; i++) {
      v.x = u.x + A->dx[i];
      v.y = u.y + A->dy[i];
      if (ValidPixel(cost,v.x,v.y)){
	q   = v.x + cost->tbrow[v.y];
	if (pred->val[q]==p){
	  cost->val[q]=INT_MAX; pred->val[q] = NIL;
	  RemNode[last]=q; last++;
	}else{ 
	  if (_fast_BMapGet(RemRoot,root->val[q])==0){ 	                                   if (_fast_BMapGet(inFrontier,q)==0){
	      InsertSet(&Frontier,q); _fast_BMapSet1(inFrontier,q);
	    }
	  }
	}
      }
    }
  }

  BMapDestroy(inFrontier);
  BMapDestroy(RemRoot);
  free(RemNode);

  return(Frontier);
}
示例#6
0
CImage *DrawCBorder(Image *img, Image *label){
  CImage *border;
  int i,j,k,p,q,u,v;
  AdjRel *A;
  Image *img8;

  img8 = ConvertToNbits(img, 8);
  border = Convert2CImage(img8);
  DestroyImage(&img8);
  A = Circular(1.0);
  for(i=0;i<img->nrows;i++){
    for(j=0;j<img->ncols;j++){
      p = j + img->tbrow[i];
      for(k=1;k<A->n;k++){
	u = j+A->dx[k];
	v = i+A->dy[k];
	if(ValidPixel(img,u,v)){
	  q= u + img->tbrow[v];
	  if (label->val[p] < label->val[q]){
	    switch( label->val[q]){
	    case 0:
	      border->C[0]->val[p] = 255;
	      border->C[1]->val[p] = 255;
	      border->C[2]->val[p] = 255;	    
	      break;
	    case 1:
	      border->C[0]->val[p] = 255;
	      border->C[1]->val[p] = 0;
	      border->C[2]->val[p] = 0;	      
	      break;
	    case 2:
	      border->C[0]->val[p] = 0;
	      border->C[1]->val[p] = 255;
	      border->C[2]->val[p] = 0;	      
	      break;
	    case 3:
	      border->C[0]->val[p] = 0;
	      border->C[1]->val[p] = 0;
	      border->C[2]->val[p] = 255;
	      break;
	    default:
	      border->C[0]->val[p] = 255;
	      border->C[1]->val[p] = 255;
	      border->C[2]->val[p] = 0;
	    }
	    
	    break;
	  }
	}
      }
    }
  }
  DestroyAdjRel(&A);

  return border;
}
示例#7
0
Image *WaterGray(Image *img, Image *marker, AdjRel *A)
{
  Image *cost=NULL,*label=NULL, *pred=NULL;
  GQueue *Q=NULL;
  int i,p,q,tmp,n,lambda=1;
  Pixel u,v;

  n     = img->ncols*img->nrows;
  cost  = CreateImage(img->ncols,img->nrows);
  label = CreateImage(img->ncols,img->nrows);
  pred  = CreateImage(img->ncols,img->nrows);
  Q     = CreateGQueue(MaximumValue(marker)+2,n,cost->val);

  // Trivial path initialization

  for (p=0; p < n; p++) {
    cost->val[p]=marker->val[p]+1;
    pred->val[p]=NIL;
    InsertGQueue(&Q,p);
  }

  // Path propagation

  while(!EmptyGQueue(Q)) {
    p=RemoveGQueue(Q);
    if (pred->val[p]==NIL) { // on-the-fly root detection
      cost->val[p] =img->val[p];
      label->val[p]=lambda; lambda++;
    }
    u.x = p%img->ncols;
    u.y = p/img->ncols;
    for (i=1; i < A->n; i++){
      v.x = u.x + A->dx[i];
      v.y = u.y + A->dy[i];
      if (ValidPixel(img,v.x,v.y)){
	q = v.x + img->tbrow[v.y];
	if (cost->val[q] > cost->val[p]){
	  tmp = MAX(cost->val[p],img->val[q]);
	  if (tmp < cost->val[q]){
	    RemoveGQueueElem(Q,q);
	    pred->val[q]  = p;
	    label->val[q] = label->val[p];
	    cost->val[q]  = tmp;
	    InsertGQueue(&Q,q);
	  }
	}
      }
    }
  }
  DestroyGQueue(&Q);
  DestroyImage(&cost);
  DestroyImage(&pred);

  return(label);
}
示例#8
0
void ComputeHistograms(Image *img, float sum[4][511], float dif[4][511])
{
  ulong x, y, p, q;
  ulong npixels;
  AdjRel *A;
  int i, j;
  Pixel v;
  
  A = Circular(1.5);

  for (i=0; i<4; i++)
    for (j=0; j<=510; j++){
      sum[i][j] = 0.0;
      dif[i][j] = 0.0;
    }

  for(y=1; y<img->nrows-1; y++){
    for(x=1; x<img->ncols-1; x++){
      p = x + img->tbrow[y];
      for (i=1; i <= A->n>>1; i++){
        v.x = x + A->dx[i];
        v.y = y + A->dy[i];
        q = v.x + img->tbrow[v.y];
        if (ValidPixel(img,v.x,v.y)){
          sum[i - 1][img->val[p] + img->val[q]] += 1.0;
          dif[i - 1][img->val[p] - img->val[q] + 255] += 1.0;
        }
      }
    }
  }
  DestroyAdjRel(&A);

  npixels = img->ncols * img->nrows;
  for (i=0; i<4; i++)
    for (j=0; j<=510; j++){
      sum[i][j] /= (float) npixels;
      dif[i][j] /= (float) npixels;
    }
}
示例#9
0
void DiffWatershed(Image *grad, ImageForest *fst, Set *Obj, Set *Bkg, Set *Rm)
{
  AdjRel *A=NULL;
  GQueue *Q=NULL;
  Pixel   u,v;
  int     i,p,q,n,tmp,Cmax=MaximumValue(grad);
  Set    *aux, *Frontier=NULL;
  Image  *cost=fst->cost,*pred=fst->pred,*label=fst->label,*root=fst->root;

  n     = grad->ncols*grad->nrows;
  Q     = CreateGQueue(Cmax+1,n,cost->val);
  A     = Circular(1.5);

  if (Rm != NULL) { // Treat removed trees
    Frontier = ForestRemoval(fst,Rm,A);
    while (Frontier != NULL) {
      p = RemoveSet(&Frontier);
      InsertGQueue(&Q,p);
    }
  }
 
  /* Trivial path initialization for new seeds */

  aux = Obj;
  while(aux != NULL){
    p=aux->elem;
    if (Q->L.elem[p].color == GRAY) { /* p is also a frontier pixel,
		but the priority is it as a seed. */
      RemoveGQueueElem(Q,p);
    }
    label->val[p]=1; cost->val[p]=0; root->val[p]=p; pred->val[p]=NIL; 
    InsertGQueue(&Q,p);
    aux = aux->next;
  }

  aux = Bkg;
  while(aux != NULL){
    p=aux->elem;
    if (Q->L.elem[p].color == GRAY) { /* p is also a frontier pixel,
		but the priority is it as a seed. */
      RemoveGQueueElem(Q,p);
    }
    label->val[p]=0; cost->val[p]=0; root->val[p]=p; pred->val[p]=NIL;
    InsertGQueue(&Q,p);
    aux = aux->next;
  }

  /* Path propagation */

  while (!EmptyGQueue(Q)){
    p   = RemoveGQueue(Q);
    u.x = p%grad->ncols;
    u.y = p/grad->ncols;
    for (i=1; i < A->n; i++) {
      v.x = u.x + A->dx[i];
      v.y = u.y + A->dy[i];
      if (ValidPixel(grad,v.x,v.y)){
	q   = v.x + grad->tbrow[v.y];
	if (Q->L.elem[q].color != BLACK) {
	  tmp = MAX(cost->val[p] , grad->val[q]);
	  if ((tmp < cost->val[q])||(pred->val[q]==p)){
	    if (Q->L.elem[q].color == GRAY) { 
	      RemoveGQueueElem(Q,q);
	    }
	    cost->val[q]  = tmp;
	    label->val[q] = label->val[p];
	    root->val[q]  = root->val[p];
	    pred->val[q]  = p; 
	    InsertGQueue(&Q,q);
	  }
	}
      }
    }
  }

  DestroyGQueue(&Q);
  DestroyAdjRel(&A);
}
示例#10
0
      /*
      * Given a pixel and image dimension, retrieve its neighbor
      * If neighbor is out of the image range, return (-1,-1) coord
      * @param x Input x pixel coord
      * @param y Input y pixel coord
      * @param dir Neighbor direction to retrieve
      * @param img_width Width of the image
      * @param img_height Height of the image
      * @param[out] nx Neighbor x pixel coord
      * @param[out] ny Neighbor y pixel coord
      * @return true if input params are all good | false if dir is incorrect
      */
      static inline bool GetNeighbor( const int x , const int y ,
                                      const PixelNeighborsDirection dir ,
                                      const int img_width , const int img_height ,
                                      int & nx , int & ny )
      {
        nx = x;
        ny = y;

        switch (dir)
        {
        case PIXEL_TOP_LEFT :
        {
          nx -= 1;
          ny -= 1;
          break;
        }
        case PIXEL_TOP :
        {
          ny -= 1;
          break;
        }
        case PIXEL_TOP_RIGHT :
        {
          nx += 1;
          ny -= 1;
          break;
        }
        case PIXEL_LEFT :
        {
          nx -= 1;
          break;
        }
        case PIXEL_RIGHT:
        {
          nx += 1;
          break;
        }
        case PIXEL_BOTTOM_LEFT:
        {
          nx -= 1;
          ny += 1;
          break;
        }
        case PIXEL_BOTTOM :
        {
          ny += 1;
          break;
        }
        case PIXEL_BOTTOM_RIGHT :
        {
          nx += 1;
          ny += 1;
          break;
        }
        default:
        {
          std::cerr << "Unhandled pixel direction" << std::endl;
          return false;
        }
        }

        if (! ValidPixel( nx , ny , img_width , img_height ) )
        {
          nx = -1;
          ny = -1;
        }
        return true;
      }
示例#11
0
      /**
      * @brief Extract MSER regions
      * @param img Input image
      * @param[out] regions Output regions
      */
      void MSERExtractor::Extract( const image::Image<unsigned char> & img , std::vector<MSERRegion> & regions ) const
      {
        // Compute minimum and maximum region area relative to this image
        const int minRegArea = img.Width() * img.Height() * m_minimum_area;
        const int maxRegArea = img.Width() * img.Height() * m_maximum_area;

        // List of processed pixels (maybe we can use a more efficient structure)
        std::vector<std::vector<bool >> processed;
        processed.resize( img.Width() );
        for (int i = 0; i < img.Width(); ++i )
        {
          processed[ i ].resize( img.Height() );
          std::fill( processed[ i ].begin() , processed[ i ].end() , false );
        }

        // Holds the boundary of given grayscale value (boundary[0] -> pixels in the boundary with 0 grayscale value)
        std::vector<PixelStackElt> boundary[ 256 ];

        // List of regions computed so far (not only valid MSER regions)
        std::vector<MSERRegion *> regionStack;

        // Push en empty region
        regionStack.push_back( new MSERRegion );

        // Start processing from top left pixel
        PixelStackElt cur_pix;
        cur_pix.pix_x = 0;
        cur_pix.pix_y = 0;
        cur_pix.pix_level = img( 0 , 0 );
        cur_pix.edge_index = PIXEL_RIGHT;

        processed[ cur_pix.pix_x ][ cur_pix.pix_y ] = true;

        regionStack.push_back( new MSERRegion( cur_pix.pix_level , cur_pix.pix_x , cur_pix.pix_y ) );

        int priority = 256;

        // Start process
        while (1)
        {
          bool restart = false;

          // Process neighboring to see if there's something to search with lower grayscale level
          for ( PixelNeighborsDirection curDir = cur_pix.edge_index;
                curDir <= PIXEL_BOTTOM_RIGHT;
                curDir = NextDirection( curDir , m_connectivity ) )
          {
            int nx , ny;
            GetNeighbor( cur_pix.pix_x , cur_pix.pix_y , curDir , img.Width() , img.Height() , nx , ny );

            // Pixel was not processed before
            if (ValidPixel( nx , ny , img.Width() , img.Height() ) && ! processed[ nx ][ ny ] )
            {
              const int nLevel = img( ny , nx );
              processed[ nx ][ ny ] = true;

              // Info of the neighboring pixel
              PixelStackElt n_elt;
              n_elt.pix_x = nx;
              n_elt.pix_y = ny;
              n_elt.pix_level = nLevel;
              n_elt.edge_index = PIXEL_RIGHT;

              // Now look from which pixel do we have to continue
              if (nLevel >= cur_pix.pix_level )
              {
                // Continue from the same pixel
                boundary[ nLevel ].push_back( n_elt );

                // Store the lowest value so far
                priority = std::min( nLevel , priority );
              }
              else
              {
                // Go on with the neighboring pixel (go down)
                cur_pix.edge_index = NextDirection( curDir , m_connectivity ); // Next time we have to process the next boundary pixel
                boundary[ cur_pix.pix_level ].push_back( cur_pix );

                // Store the lowest value so far
                priority = std::min( cur_pix.pix_level , priority );

                // Push the next pixel to process
                cur_pix = n_elt;
                restart = true;
                break;
              }
            }
          }
          // Do we have to restart from a new pixel ?
          if (restart )
          {
            // If so it's that because we found a lower grayscale value so let's start a new region
            regionStack.push_back( new MSERRegion( cur_pix.pix_level , cur_pix.pix_x , cur_pix.pix_y ) );
            continue;
          }

          // We have process all the neighboring pixels, current pixel is the lowest we have found so far
          // now process the current pixel
          regionStack.back()->AppendPixel( cur_pix.pix_x , cur_pix.pix_y );

          // End of the process : we have no boundary region, compute MSER from graph
          if (priority == 256 )
          {
            regionStack.back()->ComputeMSER( m_delta , minRegArea , maxRegArea , m_max_variation , m_min_diversity , regions );
            break;
          }

          PixelStackElt next_pix = boundary[ priority ].back();
          boundary[ priority ].pop_back();

          // Get the next pixel level
          while (boundary[ priority ].empty() && ( priority < 256 ))
          {
            ++priority;
          }

          // Clear the stack
          const int newLevel = next_pix.pix_level;

          // Process the current stack of pixels if the next processing pixel is not at the same curent level
          if (newLevel != cur_pix.pix_level )
          {
            // Try to merge the regions to fomr a tree
            ProcessStack( newLevel , next_pix.pix_x , next_pix.pix_y , regionStack );
          }

          // Update next pixel for processing
          cur_pix = next_pix;
        }

        // Clear region stack created so far
        for (size_t i = 0; i < regionStack.size(); ++i )
        {
          delete regionStack[ i ];
        }
      }
示例#12
0
void PixelMap::BlobGrowing(int step, int StartWindowX, int StartWindowY, int EndWindowX, int EndWindowY)
{  

//cout << "----> BlobGrowing    [ok]" << endl;

/* int time = 0; */

map < pair <int,int>, char > EquivSet;
map < pair <int,int>, char > EquivSwap;

map < pair <int,int>, char >::iterator EquivItr;
map < pair <int,int>, char >::iterator SwapItr;
map < pair <int,int>, char >::iterator NewItr;

vector < Equivalence > NewEquiv;
vector < Equivalence >::iterator NewEquivItr1;
vector < Equivalence >::iterator NewEquivItr2;
vector < Equivalence >::iterator NewEquivItr;

	
int rowstride = mWidth*Pixel4Byte;  

	  
map < char, map< int,Blob* > >::iterator mBlobsItr;

	
map < int,Blob* >::iterator BlobItr;

	
for(mBlobsItr = mBlobs.begin(); mBlobsItr != mBlobs.end(); mBlobsItr++)   
{
	for(BlobItr = mBlobsItr->second.begin(); BlobItr != mBlobsItr->second.end(); BlobItr++)
	{
		delete BlobItr->second;
	}

   	mBlobsItr->second.clear();
}

mBlobs.clear();

nextBlobId=1;
  
for(unsigned int k=0 ; k<prev_line.size() ;k++)
{
    prev_line[k]=0; //vector
}

for(unsigned int k=0 ; k<curr_line.size() ;k++) 
{
   curr_line[k]=0;  //vector

}



// This is to classify the whole image :)
if(StartWindowX == -1) StartWindowX=0;
if(StartWindowY == -1) StartWindowY=0;
if(EndWindowX == -1) EndWindowX=mWidth;
if(EndWindowY == -1) EndWindowY=mHeight;

if(StartWindowX > EndWindowX)
{
      int swap;
      swap = StartWindowX;
      StartWindowX = EndWindowX;
      EndWindowX = swap;
}

if(StartWindowY > EndWindowY)
{
      int swap;
      swap = StartWindowY;
      StartWindowY = EndWindowY;
      EndWindowY = swap;
}


/* time = getTime(); */

	


for(int i=StartWindowY; i < EndWindowY; i+=step)
{
	for(int j=StartWindowX; j < EndWindowX; j+=step)
    	{
		mColorImage[mWidth*i+j]=mColor->get_color((unsigned int)*((mImage + i*rowstride + j*Pixel4Byte)+0), 
							  (unsigned int)*((mImage + i*rowstride + j*Pixel4Byte)+1),
							  (unsigned int)*((mImage + i*rowstride + j*Pixel4Byte)+2));
	}
}



//printf("\tTiming:: To do Classification \t= %d\n", getTime()-time);     

// Begin the blob growing code

/* time = getTime();*/

  for(int i=StartWindowY; i<EndWindowY;i=i+step)	
    {
      for(int j=StartWindowX; j<EndWindowX;j=j+step)
	{
	 if(i==StartWindowY && j==StartWindowX) //################# First Pixel
	  {
	    PxLabel0 = (char)mColorImage[mWidth * i + j];
	    if(ValidPixel(PxLabel0))
	      {
		mBlobs[PxLabel0][nextBlobId] = new Blob(nextBlobId,i,j);
		curr_line[j]=nextBlobId++;
	      }
	  }
	  else if (i==StartWindowY && j!=StartWindowX) //########################### First Row
	    {
	      PxLabel0 = (char)mColorImage[mWidth*i + j];
	      if(ValidPixel(PxLabel0))
		{ 
		  PxLabel1=(char)mColorImage[mWidth*i + (j-step)];
		  if(PxLabel0==PxLabel1){
		    curr_line[j]=curr_line[j-step];
		    mBlobs[PxLabel0][curr_line[j]]->merge(i,j);
		  }
		  else{
		    mBlobs[PxLabel0][nextBlobId] = new Blob(nextBlobId,i,j);
		    curr_line[j]=nextBlobId++;
		  }
		}
	    }
	  else if (i!=StartWindowY && j==StartWindowX) //################# First Column
	    {
	      PxLabel0 = (char)mColorImage[mWidth*i + j];
	      if(ValidPixel(PxLabel0))
		{   
		  PxLabel3=(char)mColorImage[mWidth*(i-step) + j]; 
		  PxLabel4=(char)mColorImage[mWidth*(i-step) + (j+step)];
		  if(PxLabel0==PxLabel3){
		    if((curr_line[j]!=0) && (prev_line[j]!=0) && (curr_line[j]!=prev_line[j]))
		      {
			if(curr_line[j]<prev_line[j]){
			  pair<int,int> p(curr_line[j],prev_line[j]);
			  EquivSet[p]=PxLabel0;
			}else{ 
			  pair<int,int> p(prev_line[j],curr_line[j]);
			  EquivSet[p]=PxLabel0;
			}   
			//Equivalence E(curr_line[j],prev_line[j],PxLabel0);
			//EquivSet.insert(E);
		      }
		    else if(curr_line[j]==0 && prev_line[j]!=0){
		      curr_line[j]=prev_line[j];
		      mBlobs[PxLabel0][curr_line[j]]->merge(i,j);
		    }
		  }
		  if(PxLabel0==PxLabel4){
		    if((curr_line[j]!=0) && (prev_line[j+1]!=0) && (curr_line[j]!=prev_line[j+1])) 
		      {
			if(curr_line[j]<prev_line[j+step]){
			  pair<int,int> p(curr_line[j],prev_line[j+step]);
			  EquivSet[p]=PxLabel0;
			}else{
			  pair<int,int> p(prev_line[j+step],curr_line[j]);
			  EquivSet[p]=PxLabel0;
			}
			//Equivalence E(curr_line[j],prev_line[j+1],PxLabel0);
			//EquivSet.insert(E);
		      }
		    else if(curr_line[j]==0 && prev_line[j+step]!=0){
		      curr_line[j]=prev_line[j+step];
		      mBlobs[PxLabel0][curr_line[j]]->merge(i,j);
		    }
		  }
		  if(PxLabel0 != PxLabel3 && PxLabel0 != PxLabel4){
			mBlobs[PxLabel0][nextBlobId] = new Blob(nextBlobId,i,j);
		    curr_line[j]=nextBlobId++;
		  }
		}
	    }
	  else if (j==EndWindowX-step) //################################# Last Column
	    {
	      PxLabel0 = (char)mColorImage[mWidth*i + j];
	      if(ValidPixel(PxLabel0))
		{   
		  PxLabel1=(char)mColorImage[mWidth*i + (j-step)];
		  PxLabel2=(char)mColorImage[mWidth*(i-step) + (j-step)];
		  PxLabel3=(char)mColorImage[mWidth*(i-step) + j];
		  if(PxLabel0==PxLabel1){
		    if((curr_line[j]!=0) && (curr_line[j-step]!=0) && (curr_line[j]!=curr_line[j-step]))
		      {
			if(curr_line[j]<curr_line[j-step]){
			  pair<int,int> p(curr_line[j],curr_line[j-step]);
			  EquivSet[p]=PxLabel0;
			}else{
			  pair<int,int> p(curr_line[j-step],curr_line[j]);
			  EquivSet[p]=PxLabel0;
			}
			//Equivalence E(curr_line[j],curr_line[j-1],PxLabel0);
			//EquivSet.insert(E);
		      }
		    else if(curr_line[j]==0 && curr_line[j-step]!=0){
		      curr_line[j]=curr_line[j-step];
		      mBlobs[PxLabel0][curr_line[j]]->merge(i,j);
		    }
		  }
		  if(PxLabel0==PxLabel2){
		    if((curr_line[j]!=0) && (prev_line[j-step]!=0) && (curr_line[j]!=prev_line[j-step]))
		      {
			if(curr_line[j]<prev_line[j-step]){
			  pair<int,int> p(curr_line[j],prev_line[j-step]);
			  EquivSet[p]=PxLabel0;
			}else{
			  pair<int,int> p(prev_line[j-step],curr_line[j]);
			  EquivSet[p]=PxLabel0;
			}
			//Equivalence E(curr_line[j],prev_line[j-1],PxLabel0);
			//EquivSet.insert(E);
		      }
		    else if(curr_line[j]==0 && prev_line[j-step]!=0){
		      curr_line[j]=prev_line[j-step];
		      mBlobs[PxLabel0][curr_line[j]]->merge(i,j);
		    }
		  }
		  if(PxLabel0==PxLabel3){
		    if((curr_line[j]!=0) && (prev_line[j]!=0) && (curr_line[j]!=prev_line[j]))
		      {
			if(curr_line[j]<prev_line[j]){
			  pair<int,int> p(curr_line[j],prev_line[j]);
			  EquivSet[p]=PxLabel0;
			}else{
			  pair<int,int> p(prev_line[j],curr_line[j]);
			  EquivSet[p]=PxLabel0;
			}
			//Equivalence E(curr_line[j],prev_line[j],PxLabel0);
			//EquivSet.insert(E);
		      }
		    else if(curr_line[j]==0 && prev_line[j]!=0){
		      curr_line[j]=prev_line[j];
		      mBlobs[PxLabel0][curr_line[j]]->merge(i,j); 
		    }
		  }
		  if(PxLabel0 != PxLabel1 && PxLabel0 != PxLabel2 && PxLabel0 != PxLabel3){
		    mBlobs[PxLabel0][nextBlobId] = new Blob(nextBlobId,i,j);
		    curr_line[j]=nextBlobId++;
		  }
		}
	    }
	  else //################################################################################ Generic Case
	  {
	    PxLabel0 = (char)mColorImage[mWidth*i + j];
	    if(ValidPixel(PxLabel0))
	      {
		PxLabel1=(char)mColorImage[mWidth*i + (j-step)];
		PxLabel2=(char)mColorImage[mWidth*(i-step) + (j-step)];
		PxLabel3=(char)mColorImage[mWidth*(i-step) + j];
		PxLabel4=(char)mColorImage[mWidth*(i-step) + (j+step)];
		if(PxLabel0==PxLabel1){
		  if((curr_line[j]!=0 && (curr_line[j-step]!=0) && (curr_line[j]!=curr_line[j-step]))) 
		    {
		      if(curr_line[j]<curr_line[j-step]){
			pair<int,int> p(curr_line[j],curr_line[j-step]);
			EquivSet[p]=PxLabel0;
		      }else{
			pair<int,int> p(curr_line[j-step],curr_line[j]);
			EquivSet[p]=PxLabel0;
		      }
		      //Equivalence E(curr_line[j],curr_line[j-1],PxLabel0);
		      //EquivSet.insert(E);
		    }
		  else if(curr_line[j]==0 && curr_line[j-step]!=0 ){
		    curr_line[j]=curr_line[j-step];
		    mBlobs[PxLabel0][curr_line[j]]->merge(i,j);
		  }
		}
		if(PxLabel0==PxLabel2){
		  if((curr_line[j]!=0) && (prev_line[j-step]!=0) && (curr_line[j]!=prev_line[j-step])) 
		    {
		      if(curr_line[j]<prev_line[j-step]){
			pair<int,int> p(curr_line[j],prev_line[j-step]);
			EquivSet[p]=PxLabel0;
		      }else{
			pair<int,int> p(prev_line[j-step],curr_line[j]);
			EquivSet[p]=PxLabel0;
		      }
		      //Equivalence E(curr_line[j],prev_line[j-1],PxLabel0);
		      //EquivSet.insert(E);
		    }
		  else if(curr_line[j]==0 && prev_line[j-step]!=0){
		    curr_line[j]=prev_line[j-step];
		    mBlobs[PxLabel0][curr_line[j]]->merge(i,j);
		  }
		}
		if(PxLabel0==PxLabel3){
		  if((curr_line[j]!=0) && (prev_line[j]!=0) && (curr_line[j]!=prev_line[j])) 
		    {
		      if(curr_line[j]<prev_line[j]){
			pair<int,int> p(curr_line[j],prev_line[j]);
			EquivSet[p]=PxLabel0;
		      }else{
			pair<int,int> p(prev_line[j],curr_line[j]);
			EquivSet[p]=PxLabel0;
		      }
		      //Equivalence E(curr_line[j],prev_line[j],PxLabel0);
		      //EquivSet.insert(E);
		    }
		  else if(curr_line[j]==0 && prev_line[j]!=0){
		    curr_line[j]=prev_line[j];
		    mBlobs[PxLabel0][curr_line[j]]->merge(i,j);
		  }
		}
		if(PxLabel0==PxLabel4){
		  if((curr_line[j]!=0) && (prev_line[j+1]!=0) && (curr_line[j]!=prev_line[j+1]))
		    {
		      if(curr_line[j]<prev_line[j+1]){
			pair<int,int> p(curr_line[j],prev_line[j+step]);
			EquivSet[p]=PxLabel0;
		      }else{
			pair<int,int> p(prev_line[j+step],curr_line[j]);
			EquivSet[p]=PxLabel0;
		      }
		      //Equivalence E(curr_line[j],prev_line[j+1],PxLabel0);
		      //EquivSet.insert(E);
		    }
		  else if(curr_line[j]==0 && prev_line[j+step]!=0){
		    curr_line[j]=prev_line[j+step];
		    mBlobs[PxLabel0][curr_line[j]]->merge(i,j);
		  }
		}
		if(PxLabel0!=PxLabel1 && PxLabel0!=PxLabel2 && PxLabel0!=PxLabel3 && PxLabel0!=PxLabel4){
		  mBlobs[PxLabel0][nextBlobId] = new Blob(nextBlobId,i,j);
		  curr_line[j]=nextBlobId++;
		}
	      }
	  }
	}
      prev_line.swap(curr_line);
      for(int k=0 ; k<mWidth ;k++){
	curr_line[k]=0;
      }
    }
  
  //#ifdef DEBUG
 // printf("\tTiming:: To do BlobGrowing \t= %d\n", getTime()-time);     
  //#endif 
  
  //#ifdef DEBUG
  /* time=getTime();*/
  //#endif
  NewEquiv.clear();
  NewEquiv.reserve(EquivSet.size());

  //  for(EquivItr=EquivSet.begin(); EquivItr!=EquivSet.end(); EquivItr++)
  //    NewEquiv.push_back(*EquivItr);

  for(EquivItr=EquivSet.begin(); EquivItr!=EquivSet.end(); EquivItr++)
    {    
      Equivalence E((EquivItr->first).first,(EquivItr->first).second,EquivItr->second);
      NewEquiv.push_back(E);
    }
  
  //#ifdef DEBUG
  //printf("\tTiming:: To create new equivalence \t= %d\n", getTime()-time);     
  //#endif 
  
  //Start new equivalence resolution
  //#ifdef DEBUG
  /* time = getTime(); */
  //#endif
  if(!NewEquiv.empty())
    {
      for(NewEquivItr1=NewEquiv.begin();NewEquivItr1!=NewEquiv.end();NewEquivItr1++)
	{
	  if(NewEquivItr1->GetFirst()!=NewEquivItr1->GetSecond())
	    {
	      mBlobs[NewEquivItr1->GetClass()][NewEquivItr1->GetFirst()]->merge(mBlobs[NewEquivItr1->GetClass()][NewEquivItr1->GetSecond()]);
	      for(NewEquivItr2=NewEquivItr1; NewEquivItr2!=NewEquiv.end(); NewEquivItr2++)
		{
		  if(NewEquivItr2!=NewEquivItr1)
		    {
		      if(NewEquivItr2->GetFirst() == NewEquivItr1->GetSecond())
			{
			  NewEquivItr2->SetFirst(NewEquivItr1->GetFirst());
			}
		      if(NewEquivItr2->GetSecond() == NewEquivItr1->GetSecond())
			{
			  NewEquivItr2->SetSecond(NewEquivItr2->GetFirst());
			  NewEquivItr2->SetFirst(NewEquivItr1->GetFirst());
			}
		    }
		}
	    }
	}
    }
  //#ifdef DEBUG
  //printf("\tTiming:: To Solve Equivalence \t= %d\n", getTime()-time);
  //#endif
}