double cvDistanceLinePoint(CvPoint const &a, CvPoint const &b, CvPoint const &c, bool isSegment) { if (isSegment) { double dot1 = cvDotProductPoints(a, b, c); if (dot1>0) return cvDistancePointPoint(b, c); double dot2 = cvDotProductPoints(b, a, c); if(dot2>0) return cvDistancePointPoint(a, c); } return fabs(cvCrossProductPoints(a,b,c)/cvDistancePointPoint(a,b)); }
double cvContourPolygonPerimeter(CvContourPolygon const *p) { CV_FUNCNAME("cvContourPolygonPerimeter"); __CV_BEGIN__; { CV_ASSERT(p!=NULL); double perimeter = cvDistancePointPoint((*p)[p->size()-1], (*p)[0]); for (unsigned int i=0; i<p->size()-1; i++) perimeter+=cvDistancePointPoint((*p)[i], (*p)[i+1]); return perimeter; } __CV_END__; }
CvContourPolygon *cvSimplifyPolygon(CvContourPolygon const *p, double const delta) { CV_FUNCNAME("cvSimplifyPolygon"); __CV_BEGIN__; { CV_ASSERT(p!=NULL); CV_ASSERT(p->size()>2); double furtherDistance=0.; unsigned int furtherIndex=0; CvContourPolygon::const_iterator it=p->begin(); ++it; for (unsigned int i=1; it!=p->end(); ++it, i++) { double d = cvDistancePointPoint(*it, p->front()); if (d>furtherDistance) { furtherDistance = d; furtherIndex = i; } } if (furtherDistance<delta) { CvContourPolygon *result = new CvContourPolygon; result->push_back(p->front()); return result; } bool *pnUseFlag = new bool[p->size()]; for (int i=1; i<p->size(); i++) pnUseFlag[i] = false; pnUseFlag[0] = pnUseFlag[furtherIndex] = true; simplifyPolygonRecursive(p, 0, furtherIndex, pnUseFlag, delta); simplifyPolygonRecursive(p, furtherIndex, -1, pnUseFlag, delta); CvContourPolygon *result = new CvContourPolygon; for (int i=0; i<p->size(); i++) if (pnUseFlag[i]) result->push_back((*p)[i]); delete[] pnUseFlag; return result; } __CV_END__; }