Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 375
user1061512 Avatar asked Nov 23 '11 09:11

user1061512


1 Answers

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

like image 111
Marc Pilgaard Avatar answered Oct 14 '22 04:10

Marc Pilgaard