hi all,
ive been doing some research into simplifying contours and poly lines… haven’t been completely happy with results given by the poly_simplify algorithm i found here the forum and so just wanted to share my findings.
poly_simplify uses a Douglas-Peucker recursive simplification routine, although ive noticed it is very jump as the tolerance changes, meaning the dominant points always change position.
i tried contour simplification using openCV with much better results. the dominant points always stay the same which suggests to me it is better at recognising general shape of the curve or polygon.
here is the code,
void testApp :: simplifyDP_openCV ( const vector<ofPoint>& contourIn, vector<ofPoint>& contourOut, float tolerance )
{
//-- copy points.
int numOfPoints;
numOfPoints = contourIn.size();
CvPoint* cvpoints;
cvpoints = new CvPoint[ numOfPoints ];
for( int i=0; i<numOfPoints; i++)
{
int j = i % numOfPoints;
cvpoints[ i ].x = contourIn[ j ].x;
cvpoints[ i ].y = contourIn[ j ].y;
}
//-- create contour.
CvContour contour;
CvSeqBlock contour_block;
cvMakeSeqHeaderForArray
(
CV_SEQ_POLYLINE,
sizeof(CvContour),
sizeof(CvPoint),
cvpoints,
numOfPoints,
(CvSeq*)&contour,
&contour_block
);
printf( "length = %f \n", cvArcLength( &contour ) );
//-- simplify contour.
CvMemStorage* storage;
storage = cvCreateMemStorage( 1000 );
CvSeq *result = 0;
result = cvApproxPoly
(
&contour,
sizeof( CvContour ),
storage,
CV_POLY_APPROX_DP,
cvContourPerimeter( &contour ) * tolerance,
0
);
//-- contour out points.
contourOut.clear();
for( int j=0; j<result->total; j++ )
{
CvPoint * pt = (CvPoint*)cvGetSeqElem( result, j );
contourOut.push_back( ofPoint() );
contourOut.back().x = (float)pt->x;
contourOut.back().y = (float)pt->y;
}
//-- clean up.
if( storage != NULL )
cvReleaseMemStorage( &storage );
delete[] cvpoints;
}
also attached a testApp ive been using to test these algorithms so you can see the results for yourself.
[attachment=0:1hd8j7n2]curveAnalysis.zip[/attachment:1hd8j7n2]
L.