/****************************************************************************************** * labelBinaryImage ******************************************************************************************/ int labelBinaryImage(Image *im) { int nRows, nCols, levels; int i, j; nRows = im->getNRows( ); nCols = im->getNCols( ); /* FIRST RUN */ /* read pixel row by row, label starting from 1 */ int nextLabel = 0; DisjSets labels; for(i=0; i<nRows; i++) { for(j=0; j<nCols; j++) { /* 0 is black, 255 is white */ if (im->getPixel(i, j) != 0) { int NW, N, W; /* most pixels--except for top row and left column */ if (i!=0 && j!=0) { /* check pixels in the following order: NW, N, W */ NW = im->getPixel(i-1,j-1); N = im->getPixel(i-1,j); W = im->getPixel(i,j-1); if (NW!=0) { im->setPixel(i,j,NW); if (N!=0 && W==0 && N!=NW) { labels.unionSets(NW,N); } if (W!=0 && N==0 && W!=NW) { labels.unionSets(NW,W); } if (W!=0 && N!=0 && W!=N) { labels.unionSets(N,W); } } else { if (N!=0 && W==0) { im->setPixel(i,j,N); } else if (N==0 && W!=0) { im->setPixel(i,j,W); } else if (N==0 && W==0) { im->setPixel(i,j,++nextLabel); labels.addElement( ); } else if (N!=0 && W!=0) { if (N==W) { im->setPixel(i,j,N); } else { labels.unionSets(N,W); im->setPixel(i,j,N); } } } } /* top left corner */ if (i==0 && j==0) { im->setPixel(i,j,++nextLabel); labels.addElement( ); } /* top row */ if (i==0 && j!=0) { W = im->getPixel(i,j-1); if (W!=0) { im->setPixel(i,j,W); } else { im->setPixel(i,j,++nextLabel); labels.addElement( ); } } /* left column */ if (i!=0 && j==0) { N = im->getPixel(i-1,j); if (N!=0) { im->setPixel(i,j,N); } else { im->setPixel(i,j,++nextLabel); labels.addElement( ); } } } } } /* save # levels (num of objects) */ levels = labels.getNumberOfLevels( ); im->setColors(levels); //printf("Number of objects: %d\n", levels); /* SECOND RUN */ /* create a finalLabels vector with labels of all sets */ vector<int> finalLabels; finalLabels.push_back(-1); vector<int> listOfLevels = labels.getLevels( ); int label, numOfLabels = labels.getNumberOfLabels( ); for (i=1; i<=numOfLabels; i++) { label = labels.find(i); for (j=0; j < listOfLevels.size(); j++) { if (label==listOfLevels[j]) { label = j+1; } } finalLabels.push_back(label); } /* relabel the image */ int l; for(i=0; i<nRows; i++) { for(j=0; j<nCols; j++) { l = im->getPixel(i,j); if (l>0 && l<=finalLabels.size( )) { im->setPixel(i,j,finalLabels[l]); } } } return 0; /* OK */ }
/****************************************************************************************** * readAndLabelBinaryImage ******************************************************************************************/ int readAndLabelBinaryImage(Image *im, const char *fname) { FILE *input; char line[1024]; int nCols,nRows; int levels; int i, j; /* open it */ if (!fname || (input=fopen(fname,"r"))==0) { printf("readImage: Cannot open file\n"); return -1; } /* check for the right "magic number" */ if (fread(line,1,3,input)!=3 || strncmp(line,"P5\n",3)) { fclose(input); printf("readImage: Expected .pgm file\n"); return -1; } /* skip the comments */ do { fgets(line,sizeof line,input); } while (*line=='#'); /* read the width and height */ sscanf(line,"%d %d\n",&nCols,&nRows); im->setSize(nRows, nCols); /* read line with # of gray levels, check if binary image */ fgets(line,sizeof line,input); sscanf(line,"%d\n",&levels); if (levels!=1) { fclose(input); printf("readImage: Expected binary .pgm file\n"); return -1; } /* FIRST RUN */ /* read pixel row by row, label starting from 1 */ int nextLabel = 0; DisjSets labels; for(i=0; i<nRows; i++) { for(j=0; j<nCols; j++) { int byte = fgetc(input); if (byte==EOF) /* short file */ { fclose(input); printf("readImage: short file\n"); return -1; } else { /* 0 is black, 255 is white */ if (byte!=0) { int NW, N, W; /* most pixels--except for top row and left column */ if (i!=0 && j!=0) { /* check pixels in the following order: NW, N, W */ NW = im->getPixel(i-1,j-1); N = im->getPixel(i-1,j); W = im->getPixel(i,j-1); if (NW!=0) { im->setPixel(i,j,NW); if (N!=0 && W==0 && N!=NW) { labels.unionSets(NW,N); } if (W!=0 && N==0 && W!=NW) { labels.unionSets(NW,W); } if (W!=0 && N!=0 && W!=N) { labels.unionSets(N,W); } } else { if (N!=0 && W==0) { im->setPixel(i,j,N); } else if (N==0 && W!=0) { im->setPixel(i,j,W); } else if (N==0 && W==0) { im->setPixel(i,j,++nextLabel); labels.addElement( ); } else if (N!=0 && W!=0) { if (N==W) { im->setPixel(i,j,N); } else { labels.unionSets(N,W); im->setPixel(i,j,N); } } } } /* top left corner */ if (i==0 && j==0) { im->setPixel(i,j,++nextLabel); labels.addElement( ); } /* top row */ if (i==0 && j!=0) { W = im->getPixel(i,j-1); if (W!=0) { im->setPixel(i,j,W); } else { im->setPixel(i,j,++nextLabel); labels.addElement( ); } } /* left column */ if (i!=0 && j==0) { N = im->getPixel(i-1,j); if (N!=0) { im->setPixel(i,j,N); } else { im->setPixel(i,j,++nextLabel); labels.addElement( ); } } } } } } /* save # levels (num of objects) */ levels = labels.getNumberOfLevels( ); im->setColors(levels); printf("Number of objects: %d\n", levels); /* SECOND RUN */ /* create a finalLabels vector with labels of all sets */ vector<int> finalLabels; finalLabels.push_back(-1); vector<int> listOfLevels = labels.getLevels( ); int label, numOfLabels = labels.getNumberOfLabels( ); for (i=1; i<=numOfLabels; i++) { label = labels.find(i); for (j=0; j < listOfLevels.size(); j++) { if (label==listOfLevels[j]) { label = j+1; } } finalLabels.push_back(label); } /* relabel the image */ int l; for(i=0; i<nRows; i++) { for(j=0; j<nCols; j++) { l = im->getPixel(i,j); if (l>0 && l<=finalLabels.size( )) { im->setPixel(i,j,finalLabels[l]); } } } /* close the file */ fclose(input); return 0; /* OK */ }