I think I found a bug but I don't know what assumptions are suppose to be true for the functions findContours, convexHull, and convexityDefects. I have a contour around an image that may have a little noise because of the segmentation previous to finding contours. Some points in the contour exists multiple times (not right next to each other but with one Point in between them). I assume that is valid and when I draw the contour it looks great.
Where I think the real problem is is in convexHull. I'm calling it using
vector<int> hull;
convexHull(contour, hull);
So I expect to get back a list of indices into the contour. In cvConvexityDefects it checks the orientation of the hull points by looking at the first 3 indices of the hull.
else
{
index1 = *CV_SEQ_ELEM( hull, int, 0 );
index2 = *CV_SEQ_ELEM( hull, int, 1 );
index3 = *CV_SEQ_ELEM( hull, int, 2 );
}
sign += (index2 > index1) ? 1 : 0;
sign += (index3 > index2) ? 1 : 0;
sign += (index1 > index3) ? 1 : 0;
rev_orientation = (sign == 2) ? 0 : 1;
So it assumes that all the indices in the hull points should be decreasing or increasing. Is that correct?
I get the following list of indices as hull points with the problem bolded. Indices are decreasing until it gets to that point. This causes convexityDefects to check all the points on the contour rather than the points between the two hull points and give a bad result.
4288 4280 4278 4219 4214 3938 3936 3932 3899 3898 3896 1568 1333 1332 1029 1010 1011 1002 971 925 891 750 749 716 700 600 421 177 175 0 5839 5793 5787 5587 5585 5491 5468 5453 5395 5374 5182 4509 4492 4461 4434 4419 4417 4292