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