I have been working on a basic hand/finger tracking code using OpenCV and the ConvexHull and ConvexityDefects method.
Basically I am able to create a contour of the hand. I now need to be able to count the number of fingers. I know that the start and the end points of the Convex Hull are the finger tips but I am unsure how to count them and also how to highlight them by drawing circles on them or something.
I want my code to perform something like this.
This is a sample part of my code so far:
cvFindContours( hsv_mask, storage, &contours, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) );
CvSeq* contours2 = NULL;
CvRect rect = cvBoundingRect( contours2, 0 );
cvRectangle( bitImage, cvPoint(rect.x, rect.y + rect.height), cvPoint(rect.x + rect.width, rect.y), CV_RGB(200, 0, 200), 1, 8, 0 );
CvSeq* hull = cvConvexHull2( contours2, 0, CV_CLOCKWISE, 0 );
CvSeq* defect = cvConvexityDefects( contours2, hull, dftStorage );
CvBox2D box = cvMinAreaRect2( contours2, minStorage );
cvDrawContours( bg, contours2, CV_RGB( 0, 200, 0), CV_RGB( 0, 100, 0), 1, 1, 8, cvPoint(0,0));
I have played around with it and I can now draw the fingertip points using this code
for(;defect;defect = defect->h_next)
{
int nomdef = defect->total;
if(nomdef == 0)
continue;
defectArray = (CvConvexityDefect*)malloc(sizeof(CvConvexityDefect)*nomdef);
cvCvtSeqToArray (defect, defectArray, CV_WHOLE_SEQ);
for(i=0; i<nomdef;>
{
cvCircle( bg, *(defectArray[i].end), 5, CV_RGB(255,0,0), -1, 8,0);
cvCircle( bg, *(defectArray[i].start), 5, CV_RGB(0,0,255), -1, 8,0);
cvCircle( bg, *(defectArray[i].depth_point), 5, CV_RGB(0,255,255), -1, 8,0);
}
j++;
free(defectArray);
}
However I am still getting a lot of false positives. Also if anyone could suggest any methods to now count the fingers that would be wonderful.
One of the possibilities you have is to count the amount of defects there are. If you have done it right, the defects is suppose to be located in the bottom section between two fingers.http://img27.imageshack.us/img27/6532/herpz.jpg
Making sure you don't get any "unwanted" defects, you can use the 'depth' parameter from the CvConvexityDefect(); function to filter the low length defects. A better description of the "depth" parameter can be found here: opencv.itseez.com defect description