/// <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)); }
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); } }
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); } } } }