Exemplo n.º 1
0
        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;
        }