12

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.

LittleBobbyTables - Au Revoir
  • 32,008
  • 25
  • 109
  • 114
user1061512
  • 121
  • 1
  • 1
  • 4
  • Could you show some images resulting from running the code you have? – Chris Nov 24 '11 at 08:37
  • Also, have you come across [this question](http://stackoverflow.com/questions/6806637/convexity-defects-c-opencv) which processes a convex hull to return defects as a vector of points? I guess you would then need to process these points to extract the fingertips from the other end of the hull. This will depend on how the image actually appears, perhaps the hull extends to the image edge and you could ignore points near the edge? – Chris Nov 24 '11 at 09:05

1 Answers1

9

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

Marc Pilgaard
  • 588
  • 1
  • 5
  • 20