public override void Run() { Result = new ConnectedComponentImage(InputImage.Width, InputImage.Height, -1); var cursor = new ImageCursor(InputImage, 1); // per semplicità ignora i bordi (1 pixel) int[] neighborLabels = new int[Metric == MetricType.CityBlock ? 2 : 4]; int nextLabel = 0; var equivalences = new DisjointSets(InputImage.PixelCount); do { // prima scansione if (InputImage[cursor] == Foreground) { int labelCount = 0; if (Result[cursor.West] >= 0) { neighborLabels[labelCount++] = Result[cursor.West]; } if (Result[cursor.North] >= 0) { neighborLabels[labelCount++] = Result[cursor.North]; } if (Metric == MetricType.Chessboard) { // anche le diagonali if (Result[cursor.Northwest] >= 0) { neighborLabels[labelCount++] = Result[cursor.Northwest]; } if (Result[cursor.Northeast] >= 0) { neighborLabels[labelCount++] = Result[cursor.Northeast]; } } if (labelCount == 0) { equivalences.MakeSet(nextLabel); // crea un nuovo set Result[cursor] = nextLabel++; // le etichette iniziano da 0 } else { int l = Result[cursor] = neighborLabels[0]; // seleziona la prima for (int i = 1; i < labelCount; i++) // equivalenze { if (neighborLabels[i] != l) { equivalences.MakeUnion(neighborLabels[i], l); // le rende equivalenti } } } } } while (cursor.MoveNext()); //rende le etichette numeri consecutivi int totalLabels; int[] corresp = equivalences.Renumber(nextLabel, out totalLabels); //seconda e ultima scansione cursor.Restart(); do { int l = Result[cursor]; if (l >= 0) { Result[cursor] = corresp[l]; } }while(cursor.MoveNext()); Result.ComponentCount = totalLabels; }