Example #1
0
        public void GetTriangleList()
        {
            using var subdiv = new Subdiv2D(new Rect(0, 0, 500, 500));

            var points = new[] { new Point2f(300, 100), new Point2f(200, 300), new Point2f(400, 300) };

            subdiv.Insert(points[0]);
            subdiv.Insert(points[1]);
            subdiv.Insert(points[2]);

            var triangles = subdiv.GetTriangleList();

            Assert.Single(triangles);

            var triangleVertices = new[]
            {
                triangles[0].Item0, triangles[0].Item1, triangles[0].Item2, triangles[0].Item3, triangles[0].Item4, triangles[0].Item5,
            };

            foreach (var point in points)
            {
                Assert.Contains(point.X, triangleVertices);
                Assert.Contains(point.Y, triangleVertices);
            }
        }
        /// <summary>
        /// Perform Delaunay triangulation on a given set of landmark points.
        /// </summary>
        /// <param name="points">The landmark points to use for triangulation.</param>
        /// <returns>A list of Triangle structures that each refer to a single triangle of landmark points.</returns>
        public static IEnumerable <Triangle> GetDelaunayTriangles(IEnumerable <Point> points)
        {
            var result = new List <Triangle>();

            // calculate the bounding box around the points
            var rect = Cv2.BoundingRect(points);

            rect.Inflate(10, 10);

            // the Subdiv2D class handles Delaunay triangulation
            // first we add all points, and then start triangulation
            Vec6f[] triangles;
            using (var subdiv = new Subdiv2D(rect))
            {
                foreach (var p in points)
                {
                    var cv_p = new OpenCvSharp.Point2f(p.X, p.Y);
                    subdiv.Insert(cv_p);
                }
                triangles = subdiv.GetTriangleList();
            }

            // return result as an enumeration of triangle structs
            return(from t in triangles
                   let p1 = new Point(t[0], t[1])
                            let p2 = new Point(t[2], t[3])
                                     let p3 = new Point(t[4], t[5])
                                              where rect.Contains(p1) && rect.Contains(p2) && rect.Contains(p3)
                                              select new Triangle(p1, p2, p3));
        }
Example #3
0
        public void Run()
        {
            const int Size = 600;

            // Creates random point list
            var rand   = new Random();
            var points = Enumerable.Range(0, 100).Select(_ =>
                                                         new Point2f(rand.Next(0, Size), rand.Next(0, Size))).ToArray();

            Mat img = Mat.Zeros(Size, Size, MatType.CV_8UC3);

            foreach (var p in points)
            {
                img.Circle(p, 4, Scalar.Red, -1);
            }

            // Initializes Subdiv2D
            var subdiv = new Subdiv2D();

            subdiv.InitDelaunay(new Rect(0, 0, Size, Size));
            subdiv.Insert(points);

            // Draws voronoi diagram
            Point2f[][] facetList;
            Point2f[]   facetCenters;
            subdiv.GetVoronoiFacetList(null, out facetList, out facetCenters);

            var vonoroi = img.Clone();

            foreach (var list in facetList)
            {
                var before = list.Last();
                foreach (var p in list)
                {
                    vonoroi.Line(before, p, new Scalar(64, 255, 128), 1);
                    before = p;
                }
            }

            // Draws delaunay diagram
            Vec4f[] edgeList = subdiv.GetEdgeList();
            var     delaunay = img.Clone();

            foreach (var edge in edgeList)
            {
                var p1 = new Point(edge.Item0, edge.Item1);
                var p2 = new Point(edge.Item2, edge.Item3);
                delaunay.Line(p1, p2, new Scalar(64, 255, 128), 1);
            }

            Cv2.ImShow("voronoi", vonoroi);
            Cv2.ImShow("delaunay", delaunay);
            Cv2.WaitKey();
            Cv2.DestroyAllWindows();
        }
Example #4
0
        public void GetVoronoiFacetList()
        {
            using var subdiv = new Subdiv2D(new Rect(0, 0, 500, 500));

            var points = new[] { new Point2f(300, 100), new Point2f(200, 300), new Point2f(400, 300) };

            subdiv.Insert(points);

            subdiv.GetVoronoiFacetList(null, out var facetList, out var facetCenters);
            Assert.Equal(3, facetList.Length);
            Assert.Equal(3, facetCenters.Length);
            Assert.Equal(4, facetList[0].Length);
        }
Example #5
0
        public void Run()
        {
            const int Size = 600;

            // Creates random point list
            var rand = new Random();
            var points = Enumerable.Range(0, 100).Select(_ =>
                new Point2f(rand.Next(0, Size), rand.Next(0, Size))).ToArray();

            Mat img = Mat.Zeros(Size, Size, MatType.CV_8UC3);
            foreach (var p in points)
            {
                img.Circle(p, 4, CvColor.Red, -1);
            }

            // Initializes Subdiv2D
            var subdiv = new Subdiv2D();
            subdiv.InitDelaunay(new Rect(0, 0, Size, Size));
            subdiv.Insert(points);

            // Draws voronoi diagram
            Point2f[][] facetList;
            Point2f[] facetCenters;
            subdiv.GetVoronoiFacetList(null, out facetList, out facetCenters);

            var vonoroi = img.Clone();
            foreach (var list in facetList)
            {
                var before = list.Last();
                foreach (var p in list)
                {
                    vonoroi.Line(before, p, new CvColor(64, 255, 128), 1);
                    before = p;
                }
            }

            // Draws delaunay diagram
            Vec4f[] edgeList = subdiv.GetEdgeList();
            var delaunay = img.Clone();
            foreach (var edge in edgeList)
            {
                var p1 = new Point(edge.Item0, edge.Item1);
                var p2 = new Point(edge.Item2, edge.Item3);
                delaunay.Line(p1, p2, new CvColor(64, 255, 128), 1);
            }

            Cv2.ImShow("voronoi", vonoroi);
            Cv2.ImShow("delaunay", delaunay);
            Cv2.WaitKey();
            Cv2.DestroyAllWindows();
        }
Example #6
0
 private static IEnumerable <int[]> GetDelaunayTriangulationIndexes(Rect rect, List <Point2f> points)
 {
     rect = Cv2.BoundingRect(points).Union(rect);
     using (var subdivision = new Subdiv2D(rect))
     {
         subdivision.Insert(points);
         var triangulation = subdivision.GetTriangleList();
         foreach (var cell in triangulation)
         {
             var p1 = new Point2f(cell.Item0, cell.Item1);
             var p2 = new Point2f(cell.Item2, cell.Item3);
             var p3 = new Point2f(cell.Item4, cell.Item5);
             if (rect.Contains(p1) && rect.Contains(p2) && rect.Contains(p3))
             {
                 var indexA  = points.IndexOf(p1);
                 var indexB  = points.IndexOf(p2);
                 var indexC  = points.IndexOf(p3);
                 var indexes = new[] { indexA, indexB, indexC };
                 yield return(indexes);
             }
         }
     }
 }
Example #7
0
        private void CreateDelaunay(ref Mat img, ref Subdiv2D subdiv, ref VectorOfPointF points,
                                    bool drawAnimated, ref VectorOfVectorOfInt triangleIndexes)
        {
            PointF[] pointsArr = points.ToArray();
            foreach (PointF p in pointsArr)
            {
                subdiv.Insert(p);
                if (drawAnimated)
                {
                    Mat imgCopy = img.Clone();
                    DrawDelaunay(ref imgCopy, ref subdiv, new MCvScalar(255, 255, 255));
                    CvInvoke.Imshow("Delaunay Triangulation", imgCopy);
                }
            }

            // Unfortunately we don't get the triangles by there original point indexes.
            // We only get them with their vertex coordinates.
            // So we have to map them again to get the triangles with their point indexes.

            Size      size = img.Size;
            Rectangle rect = new Rectangle(0, 0, size.Width, size.Height);

            VectorOfInt ind = new VectorOfInt();

            int[]         indArr       = new int[3];
            Triangle2DF[] triangleList = subdiv.GetDelaunayTriangles();
            for (int i = 0; i < triangleList.Length; i++)
            {
                Triangle2DF t = triangleList[i];

                PointF ptzero = new PointF {
                    X = t.V0.X, Y = t.V0.Y
                };
                PointF[] PZero = new PointF[] { ptzero };

                PointF ptone = new PointF {
                    X = t.V1.X, Y = t.V1.Y
                };
                PointF[] POne = new PointF[] { ptone };

                PointF pttwo = new PointF {
                    X = t.V2.X, Y = t.V2.Y
                };
                PointF[] PTwo = new PointF[] { pttwo };

                VectorOfPointF pt = new VectorOfPointF();

                pt.Push(PZero);

                pt.Push(POne);
                pt.Push(PTwo);

                if (rect.Contains(new Point((int)pt[0].X, (int)pt[0].Y)) &&
                    rect.Contains(new Point((int)pt[1].X, (int)pt[1].Y)) &&
                    rect.Contains(new Point((int)pt[2].X, (int)pt[2].Y)))
                {
                    for (int j = 0; j < 3; j++)
                    {
                        for (int k = 0; k < points.Size; k++)
                        {
                            if (Math.Abs(pt[j].X - points[k].X) < 1.0 &&
                                Math.Abs(pt[j].Y - points[k].Y) < 1)
                            {
                                indArr[j] = k;
                            }
                        }
                    }
                }
                ind = new VectorOfInt(indArr);
                triangleIndexes.Push(ind);
            }
        }