// Simple Binary Connected components // (c) Andrew Senior 2006 http://www.andrewsenior.com // Preserve this header when redistributing. class pconcomps { int [] m_piLabels; int m_lIndex; int [] m_plEquivalent; int [] m_plAreas; int m_lIndicesAllocated; int m_iHeight, m_iWidth; // Take an image and label the components in it internally void Compute(PImage Im) { m_iWidth=Im.width; m_iHeight=Im.height; m_piLabels=new int[Im.width * Im.height]; m_lIndex=1; m_lIndicesAllocated=10; m_plEquivalent= new int [m_lIndicesAllocated]; m_plEquivalent[0]=0; int iIndex=0; for(int j=0; j0 && Im.pixels[iIndex]!=0) // Same colour as the left pixel if (red(Im.pixels[iIndex])==0) m_piLabels[iIndex]=0; else { if (i>0 && (red(Im.pixels[iIndex-1])!=0)) // Same colour as the left pixel { m_piLabels[iIndex]=m_piLabels[iIndex-1]; if (j>0 && (red(Im.pixels[iIndex-Im.width])!=0) && m_piLabels[iIndex]!=m_piLabels[iIndex-Im.width]) // Two regions different label adjoin MarkEquivalent(m_piLabels[iIndex], m_piLabels[iIndex-Im.width]); } else // Same colour as the pixel below if (j>0 && (red(Im.pixels[iIndex-Im.width])!=0)) m_piLabels[iIndex]=m_piLabels[iIndex-Im.width]; else // No neighbours - start a new component { m_piLabels[iIndex]=m_lIndex; // The new component will have this label NewComponent(); // All non BG components are considered same colour ie 1 } } } } RelabelEquivalents(); } void MarkEquivalent(int i, int j) { // Find the ultimate parent (equivalency) of each component int iT=m_plEquivalent[i]; int iS=m_plEquivalent[j]; // sort them if (iT>iS) { int l=iT; iT=iS; iS=l; } for( int k=iS; k=m_lIndicesAllocated) ReallocIndices(); m_plEquivalent[m_lIndex]=m_lIndex; // itself later it might get relabelled to a lower numbered component when they're found to touch m_lIndex++; // total number === Next component to allocate } void RelabelEquivalents() { // First go through and find the active components // iUsed keeps track of which ones are a "root" of equivalence // Everything, including the root is now mapped into an index so that // only the first iUsed indices are used. int lOldMax=m_lIndex; int k=0; int iUsed=0; for(k=0; kk) m_piLabels[iIndex]=m_piLabels[iIndex]-1; } for(int k2=k; k2