public int[,] BuildSegments(int width, int height, RGB[,] pixels, int k, int minSize, ConnectingMethod connectingMethod, ColorDifference difType, ref PerfomanceInfo perfomanceInfo, int[,] superPixels)
        {
            var watch = Stopwatch.StartNew();

            BuildGraph(width, height, pixels, connectingMethod, difType, superPixels);
            watch.Stop();
            perfomanceInfo.BuildingPerfomance = watch.ElapsedMilliseconds;

            watch = Stopwatch.StartNew();
            SortEdges();
            watch.Stop();
            perfomanceInfo.SortingPerfomance = watch.ElapsedMilliseconds;

            watch = Stopwatch.StartNew();
            DoAlgorithm(k);
            watch.Stop();
            perfomanceInfo.AlgorithmPerfomance = watch.ElapsedMilliseconds;

            watch = Stopwatch.StartNew();
            if (minSize > 0)
            {
                MargeSmall(minSize);
            }
            watch.Stop();
            perfomanceInfo.SmallSegmentMargingPerfomance = watch.ElapsedMilliseconds;
            return(ReindexSegments(width, height));
        }
        protected override void BuildGraph(int width, int height, RGB[,] pixels, ConnectingMethod connectingMethod, ColorDifference difType, int[,] superPixels = null)
        {
            int edgesPerNode = 0;

            if (connectingMethod == ConnectingMethod.Connected_4)
            {
                edgesPerNode = 2;
            }
            else if (connectingMethod == ConnectingMethod.Connected_8)
            {
                edgesPerNode = 4;
            }

            segments = new Segment[width * height];
            for (int i = 0; i < segments.Length; i++)
            {
                segments[i] = new Segment();
            }
            nodes = new Node[width, height];
            for (int j = 0; j < height; j++)
            {
                for (int i = 0; i < width; i++)
                {
                    nodes[i, j] = new Node();
                    int c = j * width + i;
                    // initialize node
                    nodes[i, j].Segment = segments[c];
                    // initialize component
                    segments[c].Id            = -1;
                    segments[c].Count         = 1;
                    segments[c].SegmentWeight = 0;
                    segments[c].First         = segments[c].Last = nodes[i, j];
                }
            }


            edges = new Edge[edgesPerNode * width * height];
            for (int i = 0; i < edges.Length; i++)
            {
                edges[i] = new Edge();
            }
            edgePockets = new Edge[2560];

            for (int j = 0; j < height; j++)
            {
                for (int i = 0; i < width; i++)
                {
                    int c = j * width + i;
                    // initialize edge

                    if ((i + 1) < width)
                    {
                        if (superPixels[i, j] != superPixels[i + 1, j])
                        {
                            var diff = PixelComparator.Difference(pixels[i, j], pixels[i + 1, j], difType) * 100;
                            CreateEdge(edgesPerNode * c, nodes[i, j], nodes[i + 1, j], (int)diff);
                        }
                        else if (nodes[i, j].Segment != nodes[i + 1, j].Segment)
                        {
                            MergeSegment(nodes[i, j].Segment, nodes[i + 1, j].Segment, 0);
                        }
                    }
                    if ((j + 1) < height)
                    {
                        if (superPixels[i, j] != superPixels[i, j + 1])
                        {
                            var diff = PixelComparator.Difference(pixels[i, j], pixels[i, j + 1], difType) * 100;
                            CreateEdge(edgesPerNode * c + 1, nodes[i, j], nodes[i, j + 1], (int)diff);
                        }
                        else if (nodes[i, j].Segment != nodes[i, j + 1].Segment)
                        {
                            MergeSegment(nodes[i, j].Segment, nodes[i, j + 1].Segment, 0);
                        }
                    }


                    if (connectingMethod == ConnectingMethod.Connected_8)
                    {
                        if ((i + 1 < width) && (j - 1 >= 0))
                        {
                            if (superPixels[i, j] != superPixels[i + 1, j - 1])
                            {
                                var diff = PixelComparator.Difference(pixels[i, j], pixels[i + 1, j - 1], difType) * 100;
                                CreateEdge(edgesPerNode * c + 2, nodes[i, j], nodes[i + 1, j - 1], (int)diff);
                            }
                            else if (nodes[i, j].Segment != nodes[i + 1, j - 1].Segment)
                            {
                                MergeSegment(nodes[i, j].Segment, nodes[i + 1, j - 1].Segment, 0);
                            }
                        }
                        if (((i + 1) < width) && ((j + 1) < height))
                        {
                            if (superPixels[i, j] != superPixels[i + 1, j + 1])
                            {
                                var diff = PixelComparator.Difference(pixels[i, j], pixels[i + 1, j + 1], difType) * 100;
                                CreateEdge(edgesPerNode * c + 3, nodes[i, j], nodes[i + 1, j + 1], (int)diff);
                            }
                            else if (nodes[i, j].Segment != nodes[i + 1, j + 1].Segment)
                            {
                                MergeSegment(nodes[i, j].Segment, nodes[i + 1, j + 1].Segment, 0);
                            }
                        }
                    }
                }
            }
        }
 protected abstract void BuildGraph(int width, int height, RGB[,] pixels, ConnectingMethod connectingMethod, ColorDifference difType, int[,] superPixels = null);
        protected override void BuildGraph(int width, int height, RGB[,] pixels, ConnectingMethod connectingMethod, ColorDifference difType, int[,] superPixels = null)
        {
            segments = new Segment[width * height];
            for (var id = 0; id < width * height; id++)
            {
                segments[id] = new Segment();
            }

            nodes = new Node[width, height];
            for (var j = 0; j < height; j++)
            {
                for (var i = 0; i < width; i++)
                {
                    var c = j * width + i;
                    nodes[i, j] = new Node();
                    // initialize node
                    nodes[i, j].Segment = segments[c];
                    // initialize component
                    segments[c].Id            = -1;
                    segments[c].Count         = 1;
                    segments[c].SegmentWeight = 0;
                    segments[c].First         = segments[c].Last = nodes[i, j];
                    segments[c].SumR          = pixels[i, j].Red;
                    segments[c].SumG          = pixels[i, j].Green;
                    segments[c].SumB          = pixels[i, j].Blue;
                }
            }


            edges = new List <Edge>();
            for (var j = 0; j < height; j++)
            {
                for (var i = 0; i < width; i++)
                {
                    if (i < (width - 1))
                    {
                        var diff = PixelComparator.Difference(nodes[i, j].Segment.RGB, nodes[i + 1, j].Segment.RGB, difType);
                        if (superPixels[i, j] != superPixels[i + 1, j])
                        {
                            edges.Add(new Edge(nodes[i, j], nodes[i + 1, j], diff)); // Right
                        }
                        else if (nodes[i, j].Segment != nodes[i + 1, j].Segment)
                        {
                            MergeSegment(nodes[i, j].Segment, nodes[i + 1, j].Segment, 0);
                        }
                    }


                    if (j < (height - 1))
                    {
                        var diff = PixelComparator.Difference(nodes[i, j].Segment.RGB, nodes[i, j + 1].Segment.RGB, difType);
                        if (superPixels[i, j] != superPixels[i, j + 1])
                        {
                            edges.Add(new Edge(nodes[i, j], nodes[i, j + 1], diff)); // Down
                        }
                        else if (nodes[i, j].Segment != nodes[i, j + 1].Segment)
                        {
                            MergeSegment(nodes[i, j].Segment, nodes[i, j + 1].Segment, 0);
                        }
                    }

                    if (connectingMethod == ConnectingMethod.Connected_8)
                    {
                        if (j > 0 && i < (width - 1))
                        {
                            var diff = PixelComparator.Difference(nodes[i, j].Segment.RGB, nodes[i + 1, j - 1].Segment.RGB, difType);
                            if (superPixels[i, j] != superPixels[i + 1, j - 1])
                            {
                                edges.Add(new Edge(nodes[i, j], nodes[i + 1, j - 1], diff)); // Up-Right
                            }
                            else if (nodes[i, j].Segment != nodes[i + 1, j - 1].Segment)
                            {
                                MergeSegment(nodes[i, j].Segment, nodes[i + 1, j - 1].Segment, 0);
                            }
                        }
                        if (j < (height - 1) && i < (width - 1))
                        {
                            var diff = PixelComparator.Difference(nodes[i, j].Segment.RGB, nodes[i + 1, j + 1].Segment.RGB, difType);
                            if (superPixels[i, j] != superPixels[i + 1, j + 1])
                            {
                                edges.Add(new Edge(nodes[i, j], nodes[i + 1, j + 1], diff)); // Down-Right
                            }
                            else if (nodes[i, j].Segment != nodes[i + 1, j + 1].Segment)
                            {
                                MergeSegment(nodes[i, j].Segment, nodes[i + 1, j + 1].Segment, 0);
                            }
                        }
                    }
                }
            }
        }