Finger tracking / counting using OpenCV convex hull and Convexity Defect functions

user1061512 picture user1061512 · Nov 23, 2011 · Viewed 12.5k times · Source

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.

Answer

Marc Pilgaard picture Marc Pilgaard · Nov 29, 2011

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