import java.awt.*; /** * Use row-by-row labeling algorithm to label connected components * The algorithm makes two passes over the image: one pass to record * equivalences and assign temporary labels and the second to replace each * temporary label by the label of its equivalence class. * [Reference] * Linda G. Shapiro, Computer Vision: Theory and Applications. (3.4 Connected * Components Labeling) * Rosenfeld and Pfaltz (1966) */ public class ConnectComponent { final int MAX_LABELS= 80000; int next_label = 1; /** * label and re-arrange the labels to make the numbers of label continous * @param zeroAsBg Leaving label 0 untouched */ public int[] compactLabeling(int[] image, Dimension d, boolean zeroAsBg) { //label first int[] label= labeling(image,d,zeroAsBg); int[] stat= new int[next_label+1]; for (int i=0;inext_label) System.err.println("bigger label than next_label found!"); stat[label[i]]++; } stat[0]=0; // label 0 will be mapped to 0 // whether 0 is background or not int j = 1; for (int i=1; i 0 && image[y*w+x-1] == image[y*w+x]) { k = rst[y*w+x-1]; connected = true; } // if connected to the up if (y > 0 && image[(y-1)*w+x]== image[y*w+x] && (connected = false || image[(y-1)*w+x] < k )) { k = rst[(y-1)*w+x]; connected = true; } if ( !connected ) { k = next_region; next_region++; } if ( k >= MAX_LABELS ){ System.err.println("maximum number of labels reached. " + "increase MAX_LABELS and recompile." ); System.exit(1); } rst[y*w+x]= k; // if connected, but with different label, then do union if ( x> 0 && image[y*w+x-1]== image[y*w+x] && rst[y*w+x-1]!= k ) uf_union( k, rst[y*w+x-1], parent ); if ( y> 0 && image[(y-1)*w+x]== image[y*w+x] && rst[(y-1)*w+x]!= k ) uf_union( k, rst[(y-1)*w+x], parent ); } } // Begin the second pass. Assign the new labels // if 0 is reserved for background, then the first available label is 1 next_label = 1; for (int i = 0; i < w*h; i++ ) { if (image[i]!=0 || !zeroAsBg) { rst[i] = uf_find( rst[i], parent, labels ); // The labels are from 1, if label 0 should be considered, then // all the label should minus 1 if (!zeroAsBg) rst[i]--; } } next_label--; // next_label records the max label if (!zeroAsBg) next_label--; System.out.println(next_label+" regions"); return rst; } void uf_union( int x, int y, int[] parent) { while ( parent[x]>0 ) x = parent[x]; while ( parent[y]>0 ) y = parent[y]; if ( x != y ) { if (x0 ) x = parent[x]; if ( label[x] == 0 ) label[x] = next_label++; return label[x]; } }