Пример #1
0
        // find objects
        public static Dictionary <Tuple <int, int>, List <Tuple <int, int> > > Groups(int[,] image)
        {
            // union find to store sets of all pixels in object
            UnionFind <Tuple <int, int> > unionFind = new UnionFind <Tuple <int, int> >();

            for (int x = 0; x < image.GetLength(0); x++)
            {
                for (int y = 0; y < image.GetLength(1); y++)
                {
                    if (image[x, y] == 0)
                    {
                        continue;
                    }

                    Tuple <int, int> xy = new Tuple <int, int>(x, y);
                    unionFind.Make(xy);
                    if (x > 0)
                    {
                        unionFind.Union(xy, new Tuple <int, int>(x - 1, y));
                    }
                    if (y > 0)
                    {
                        unionFind.Union(xy, new Tuple <int, int>(x, y - 1));
                    }
                }
            }

            // turns union find "inside out": (pixel->set identifier)->(set identifier->all pixels in set)
            Dictionary <Tuple <int, int>, List <Tuple <int, int> > > labels = new Dictionary <Tuple <int, int>, List <Tuple <int, int> > >();

            for (int x = 0; x < image.GetLength(0); x++)
            {
                for (int y = 0; y < image.GetLength(1); y++)
                {
                    if (image[x, y] == 0)
                    {
                        continue;
                    }

                    Tuple <int, int>         xy = new Tuple <int, int>(x, y), label = unionFind.Find(xy);
                    List <Tuple <int, int> > list;
                    if (!labels.TryGetValue(label, out list))
                    {
                        list          = new List <Tuple <int, int> >();
                        labels[label] = list;
                    }
                    list.Add(xy);
                }
            }

            return(labels);
        }
Пример #2
0
        private void inputImageBox_MouseDown(object sender, MouseEventArgs e)
        {
            if (this.data == null)
            {
                return;
            }

            int xx = e.X - (inputImageBox.Width - inputImageBox.Image.Width) / 2;
            int yy = e.Y - (inputImageBox.Height - inputImageBox.Image.Height) / 2;

            switch (currentStep)
            {
            case 5:     // Compactness
                decimal r     = (decimal)Operations.Compactness(this.prevData, xx, yy);
                decimal rLow  = Math.Floor(r * 100) / 100;
                decimal rHigh = Math.Ceiling(r * 100) / 100;
                minComp.Value = Math.Min(minComp.Value, rLow);
                maxComp.Value = Math.Max(maxComp.Value, rHigh);
                break;

            case 6:     // Area
                decimal a     = (decimal)Operations.Area(Operations.Perimeter(this.prevData, xx, yy));
                decimal aLow  = Math.Floor(a * 100) / 100;
                decimal aHigh = Math.Ceiling(a * 100) / 100;
                minArea.Value = Math.Min(minArea.Value, aLow);
                maxArea.Value = Math.Max(maxArea.Value, aHigh);
                break;

            case 7:     // Convexity
                UnionFind <Tuple <int, int> > unionFind = new UnionFind <Tuple <int, int> >();
                for (int x = 0; x < this.prevData.GetLength(0); x++)
                {
                    for (int y = 0; y < this.prevData.GetLength(1); y++)
                    {
                        if (this.prevData[x, y] == 0)
                        {
                            continue;
                        }

                        Tuple <int, int> xy = new Tuple <int, int>(x, y);
                        unionFind.Make(xy);
                        if (x > 0)
                        {
                            unionFind.Union(xy, new Tuple <int, int>(x - 1, y));
                        }
                        if (y > 0)
                        {
                            unionFind.Union(xy, new Tuple <int, int>(x, y - 1));
                        }
                    }
                }

                Tuple <int, int> root;
                try
                {
                    root = unionFind.Find(new Tuple <int, int>(xx, yy));
                }
                catch
                {
                    return;
                }
                List <Tuple <int, int> > points = new List <Tuple <int, int> >();

                for (int x = 0; x < this.prevData.GetLength(0); x++)
                {
                    for (int y = 0; y < this.prevData.GetLength(1); y++)
                    {
                        if (this.prevData[x, y] == 0)
                        {
                            continue;
                        }

                        Tuple <int, int> pos = new Tuple <int, int>(x, y);
                        if (unionFind.Find(pos) == root)
                        {
                            points.Add(pos);
                        }
                    }
                }

                double  hullArea = Operations.PolygonArea(Operations.ConvexHull(points));
                double  area     = Operations.Area(Operations.Perimeter(this.prevData, xx, yy));
                decimal c        = (decimal)(area / hullArea);
                decimal cLow     = Math.Floor(c * 100) / 100;
                decimal cHigh    = Math.Ceiling(c * 100) / 100;
                minConv.Value = Math.Min(minConv.Value, cLow);
                maxConv.Value = Math.Max(maxConv.Value, cHigh);
                break;

            default:
                break;
            }
        }