public int Breadth_First_Search(int root, int lab) { int light, gvP, Index, Len = 1000, Nei; bool rv; iVect2 P = new iVect2(0, 0); CQue Q = new CQue(Len); light = Grid[root]; if (Lab[root] == 0) { Lab[root] = lab; } Q.Put(root); while (!Q.Empty()) //============================= { Index = Q.Get(); gvP = Grid[Index]; P.Y = Index / width; P.X = Index - width * P.Y; for (int n = 0; n < 8; n++) //==================== { Nei = NeighbEqu(Index, n, width, height); rv = EquNaliDir(P, n, gvP); if (Nei < 0) { continue; } if (Grid[Nei] == light && Lab[Nei] == 0 && rv) { Lab[Nei] = lab; Q.Put(Nei); } } //============== end for (n... ============== } //================ end while ==================== return(1); } //****************** end Breadth-First-Search *************
} //***************** end EquNaliDir **************************** public int ComponentsE(Form1 fm1) { /* Labels connected components of "this" in "this->Lab" and returns * the number of components. Uses the EquNaLi connectedness. --*/ int Dir, light, i, nComp = 0, rv, x1 = 0, y1 = 0; bool adjac; iVect2 P = new iVect2(0, 0); for (int k = 0; k < width * height; k++) { Lab[k] = k; } int Len = height, jump, nStep = 50; if (Len > 2 * nStep) { jump = Len / nStep; } else { jump = 2; } fm1.progressBar1.Step = 1; for (int y = 0; y < height; y++) //================================================== { if ((y % jump) == jump - 1) { fm1.progressBar1.PerformStep(); } for (int x = 0; x < width; x++) //=========================================== { i = x + width * y; // "i" is the index of the actual pixel light = Grid[i]; P.X = x; P.Y = y; int nmax; if (y == 0) { nmax = 0; } else { nmax = 3; } for (int n = 0; n <= nmax; n++) //==== the four preceding neighbors ========= { switch (n) { case 0: x1 = x - 1; y1 = y; break; // West case 1: x1 = x - 1; y1 = y - 1; break; // North-West case 2: x1 = x; y1 = y - 1; break; // North case 3: x1 = x + 1; y1 = y - 1; break; // North-East } if (x1 < 0 || x1 >= width) { continue; } Dir = n + 4; int indN = x1 + width * y1; int lightNeib = Grid[indN]; if (lightNeib != light) { continue; } if ((Dir & 1) == 0) { adjac = true; } else { adjac = EquNaliDir(P, Dir, light); } if (adjac) { rv = SetEquivalent(i, indN); // Sets Lab[i] or Lab[indN] equal to Root } } //==================== end for (int n ... ============================= } //====================== end for (int x ... =============================== } //======================== end for (int y ... ================================= nComp = SecondRun(); // Writes indices of components from 1 to nComp to "Comp". return(nComp); // nComp+1 is the number of indices } //***************************** end ComponentsE ***********************************
public bool EquNaliDir(iVect2 P, int Dir, int ColorP) { /* Returns 'true' if the pixel lying in the direction "dir" (0 to 7) * from the pixel P is connected with P accordimg to the EquNaLi membership rule. * Can be called for any pixel, not only in the neighborhood of a singular point. * Standard coordinates. "ColorP" is the color of P. --*/ int cntP = 0, cntN = 0, col1 = -1, col2 = -1, colN = -1, x, y; if (N_Bits == 24) { MessageBox.Show("EquNaliDir is not designed for color images; return -1"); return(false); } switch (Dir) { case 0: if (P.X + 1 + width * P.Y < width * height) { colN = Grid[P.X + 1 + width * P.Y]; } else { colN = 0; } return(colN == ColorP); case 1: if (P.X < width - 1 && P.Y < height - 1) { colN = Grid[P.X + 1 + width * (P.Y + 1)]; } if (colN != ColorP) { return(false); } if (P.X < width - 1) { col1 = Grid[P.X + 1 + width * P.Y]; } if (P.Y < height - 1) { col2 = Grid[P.X + width * (P.Y + 1)]; } if (col1 != col2 || col1 == ColorP) { return(true); } break; case 2: if (P.Y < height - 1) { colN = Grid[P.X + width * (P.Y + 1)]; } return(colN == ColorP); case 3: if (P.X > 0 && P.Y < height - 1) { colN = Grid[P.X - 1 + width * (P.Y + 1)]; } if (colN != ColorP) { return(false); } if (P.X > 0) { col1 = Grid[P.X - 1 + width * P.Y]; } if (P.X > 0) { col2 = Grid[P.X + width * (P.Y + 1)]; } if (col1 != col2 || col1 == ColorP) { return(true); } break; case 4: if (P.X > 0) { colN = Grid[P.X - 1 + width * P.Y]; } return(colN == ColorP); case 5: if (P.X > 0 && P.Y > 0) { colN = Grid[P.X - 1 + width * (P.Y - 1)]; } if (colN != ColorP) { return(false); } if (P.X > 0) { col1 = Grid[P.X - 1 + width * P.Y]; } if (P.Y > 0) { col2 = Grid[P.X + width * (P.Y - 1)]; } if (col1 != col2 || col1 == ColorP) { return(true); } break; case 6: if (P.Y > 0) { colN = Grid[P.X + width * (P.Y - 1)]; } return(colN == ColorP); case 7: if (P.X < width - 1 && P.Y > 0) { colN = Grid[P.X + 1 + width * (P.Y - 1)]; } if (colN != ColorP) { return(false); } if (P.X < width - 1) { col1 = Grid[P.X + 1 + width * P.Y]; } if (P.Y > 0) { col2 = Grid[P.X + width * (P.Y - 1)]; } if (col1 != col2 || col1 == ColorP) { return(true); } break; } //:::::::::::::::::::::: end switch :::::::::::::::::::::::::::::::::: int imin, jmin; if (Dir == 3 || Dir == 5) { imin = -2; } else { imin = -1; } if (Dir == 5 || Dir == 7) { jmin = -2; } else { jmin = -1; } for (int j = jmin; j < jmin + 4; j++) //============ { y = P.Y + j; if (y < 0 || y >= height) { continue; } for (int i = imin; i < imin + 4; i++) //========= { x = P.X + i; if (x < 0 || x >= width) { continue; } int col = Grid[x + width * y]; if (col == ColorP) { cntP++; } if (col == col1) { cntN++; } } //============= end for (int i... ======= } //=============== end for (int j... ========= if (cntP == cntN) { return(ColorP > col1); } if (cntP < cntN) { return(true); } return(false); } //***************** end EquNaliDir ****************************