/// <summary> /// Convert a chain code contour to a polygon. /// </summary> /// <returns>A polygon.</returns> public CvContourPolygon ConvertToPolygon() { CvContourPolygon contour = new CvContourPolygon(); int x = StartingPoint.X; int y = StartingPoint.Y; contour.Add(new CvPoint(x, y)); if (ChainCode.Count > 0) { CvChainCode lastCode = ChainCode[0]; x += CvBlobConst.ChainCodeMoves[(int)ChainCode[0]][0]; y += CvBlobConst.ChainCodeMoves[(int)ChainCode[0]][1]; for (int i = 1; i < ChainCode.Count; i++) { if (lastCode != ChainCode[i]) { contour.Add(new CvPoint(x, y)); lastCode = ChainCode[i]; } x += CvBlobConst.ChainCodeMoves[(int)ChainCode[i]][0]; y += CvBlobConst.ChainCodeMoves[(int)ChainCode[i]][1]; } } return(contour); }
private static void SimplifyPolygonRecursive(CvContourPolygon p, int i1, int i2, bool[] pnUseFlag, double delta) { int endIndex = (i2 < 0) ? p.Count : i2; if (Math.Abs(i1 - endIndex) <= 1) { return; } Point firstPoint = p[i1]; Point lastPoint = (i2 < 0) ? p[0] : p[i2]; double furtherDistance = 0.0; int furtherIndex = 0; for (int i = i1 + 1; i < endIndex; i++) { double d = DistanceLinePoint(firstPoint, lastPoint, p[i]); if ((d >= delta) && (d > furtherDistance)) { furtherDistance = d; furtherIndex = i; } } if (furtherIndex > 0) { pnUseFlag[furtherIndex] = true; SimplifyPolygonRecursive(p, i1, furtherIndex, pnUseFlag, delta); SimplifyPolygonRecursive(p, furtherIndex, i2, pnUseFlag, delta); } }
/// <summary> /// Write a contour to a SVG file. /// </summary> /// <param name="polygon">Polygon contour.</param> /// <param name="fileName">File name.</param> public static void WriteContourPolygonSvg(CvContourPolygon polygon, string fileName) { if (polygon == null) { throw new ArgumentNullException(nameof(polygon)); } polygon.WriteAsSvg(fileName); }
/// <summary> /// Draw a polygon. /// </summary> /// <param name="contour">Polygon contour.</param> /// <param name="img">Image to draw on.</param> /// <param name="color">Color to draw (default, white).</param> public static void RenderContourPolygon(CvContourPolygon contour, IplImage img, CvScalar color) { if (contour == null) { throw new ArgumentNullException("contour"); } contour.Render(img, color); }
/// <summary> /// Calculates convex hull of a contour. /// Uses the Melkman Algorithm. Code based on the version in http://w3.impa.br/~rdcastan/Cgeometry/. /// </summary> /// <param name="polygon">Contour (polygon type).</param> /// <returns>Convex hull.</returns> public static CvContourPolygon PolygonContourConvexHull(CvContourPolygon polygon) { if (polygon == null) { throw new ArgumentNullException("polygon"); } return(polygon.ContourConvexHull()); }
/// <summary> /// Calculates area of a polygonal contour. /// </summary> /// <param name="polygon">Contour (polygon type).</param> /// <returns>Area of the contour.</returns> public static double ContourPolygonArea(CvContourPolygon polygon) { if (polygon == null) { throw new ArgumentNullException(nameof(polygon)); } return(polygon.Area()); }
/// <summary> /// Draw a polygon. /// </summary> /// <param name="contour">Polygon contour.</param> /// <param name="img">Image to draw on.</param> /// <param name="color">Color to draw (default, white).</param> public static void RenderContourPolygon(CvContourPolygon contour, Mat img, Scalar color) { if (contour == null) { throw new ArgumentNullException(nameof(contour)); } contour.Render(img, color); }
/// <summary> /// Draw a polygon. /// </summary> /// <param name="contour">Polygon contour.</param> /// <param name="img">Image to draw on.</param> public static void RenderContourPolygon(CvContourPolygon contour, Mat img) { if (contour == null) { throw new ArgumentNullException("contour"); } contour.Render(img); }
/// <summary> /// Draw a polygon. /// </summary> /// <param name="contour">Polygon contour.</param> /// <param name="img">Image to draw on.</param> public static void RenderContourPolygon(CvContourPolygon contour, IplImage img) { if (contour == null) { throw new ArgumentNullException(nameof(contour)); } contour.Render(img); }
/// <summary> /// Write a contour to a CSV (Comma-separated values) file. /// </summary> /// <param name="polygon">Polygon contour.</param> /// <param name="filename">File name.</param> public static void WriteContourPolygonCsv(CvContourPolygon polygon, string filename) { if (polygon == null) { throw new ArgumentNullException("polygon"); } polygon.WriteAsCsv(filename); }
/// <summary> /// Simplify a polygon reducing the number of vertex according the distance "delta". /// Uses a version of the Ramer-Douglas-Peucker algorithm (http://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm). /// </summary> /// <param name="polygon">Contour (polygon type).</param> /// <param name="delta">Minimun distance.</param> /// <returns>A simplify version of the original polygon.</returns> public static CvContourPolygon SimplifyPolygon(CvContourPolygon polygon, double delta) { if (polygon == null) { throw new ArgumentNullException("polygon"); } return(polygon.Simplify(delta)); }
/// <summary> /// Calculates perimeter of a chain code contour. /// </summary> /// <param name="polygon">Contour (polygon type).</param> /// <returns>Perimeter of the contour.</returns> public static double ContourPolygonPerimeter(CvContourPolygon polygon) { if (polygon == null) { throw new ArgumentNullException("polygon"); } return(polygon.Perimeter()); }
/// <summary> /// Simplify a polygon reducing the number of vertex according the distance "delta". /// Uses a version of the Ramer-Douglas-Peucker algorithm (http://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm). /// </summary> /// <param name="polygon">Contour (polygon type).</param> /// <returns>A simplify version of the original polygon.</returns> public static CvContourPolygon SimplifyPolygon(CvContourPolygon polygon) { if (polygon == null) { throw new ArgumentNullException(nameof(polygon)); } return(polygon.Simplify()); }
/// <summary> /// Calculates the circularity of a polygon (compactness measure). /// </summary> /// <param name="polygon">Contour (polygon type).</param> /// <returns>Circularity: a non-negative value, where 0 correspond with a circumference.</returns> public static double ContourPolygonCircularity(CvContourPolygon polygon) { if (polygon == null) { throw new ArgumentNullException("polygon"); } return(polygon.Circularity()); }
/// <summary> /// Write a contour to a SVG file. /// </summary> /// <param name="polygon">Polygon contour.</param> /// <param name="fileName">File name.</param> /// <param name="stroke">Stroke color (black by default).</param> /// <param name="fill">Fill color (white by default).</param> public static void WriteContourPolygonSvg(CvContourPolygon polygon, string fileName, CvScalar stroke, CvScalar fill) { if (polygon == null) { throw new ArgumentNullException("polygon"); } polygon.WriteAsSvg(fileName, stroke, fill); }
/// <summary> /// Simplify a polygon reducing the number of vertex according the distance "delta". /// Uses a version of the Ramer-Douglas-Peucker algorithm (http://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm). /// </summary> /// <param name="delta">Minimun distance.</param> /// <returns>A simplify version of the original polygon.</returns> public CvContourPolygon Simplify(double delta) { double furtherDistance = 0.0; int furtherIndex = 0; if (Count == 0) { return(new CvContourPolygon()); } for (int i = 1; i < Count; i++) { double d = DistancePointPoint(this[i], this[0]); if (d > furtherDistance) { furtherDistance = d; furtherIndex = i; } } if (furtherDistance < delta) { CvContourPolygon result = new CvContourPolygon(); result.Add(this[0]); return(result); } else { bool[] pnUseFlag = new bool[Count]; for (int i = 1; i < Count; i++) { pnUseFlag[i] = false; } pnUseFlag[0] = pnUseFlag[furtherIndex] = true; SimplifyPolygonRecursive(this, 0, furtherIndex, pnUseFlag, delta); SimplifyPolygonRecursive(this, furtherIndex, -1, pnUseFlag, delta); CvContourPolygon result = new CvContourPolygon(); for (int i = 0; i < Count; i++) { if (pnUseFlag[i]) { result.Add(this[i]); } } return(result); } }
/// <summary> /// Simplify a polygon reducing the number of vertex according the distance "delta". /// Uses a version of the Ramer-Douglas-Peucker algorithm (http://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm). /// </summary> /// <param name="polygon">Contour (polygon type).</param> /// <returns>A simplify version of the original polygon.</returns> public static CvContourPolygon SimplifyPolygon(CvContourPolygon polygon) { return(polygon.Simplify()); }
/// <summary> /// Write a contour to a SVG file. /// </summary> /// <param name="polygon">Polygon contour.</param> /// <param name="fileName">File name.</param> public static void WriteContourPolygonSvg(CvContourPolygon polygon, string fileName) { polygon.WriteAsSvg(fileName); }