2 Stimmen

Wie kann ich die Anzahl der Finger berechnen? (openCV + Kontur-Erkennung)

Ich fange an, Handkontur zu finden mit findContour aber wenn ich den Finger mit convHull2 y convextyDefect Ich weiß nicht, was ich tun soll.

Könnten Sie mir bitte helfen? Hier ist mein Code:

if( cascade1 )
{
static CvMemStorage* storage4 = 0;
static CvMemStorage* storage5 = 0;
static CvMemStorage* storage6 = 0;
static CvMemStorage* storage7 = 0;

CvSeq* contours;
CvSeq* hand_contour = NULL;

// There can be more than one hand in an image. So create a growable sequence of hands.
// Detect the objects and store them in the sequence
CvSeq* handsO = cvHaarDetectObjects( img, cascade1, storage1,1.1, 2, CV_HAAR_DO_CANNY_PRUNING,cvSize(40, 40) );

storage4 = cvCreateMemStorage(0);
storage5 = cvCreateMemStorage(0);
storage6 = cvCreateMemStorage(0);
storage7 = cvCreateMemStorage(0);

cvClearMemStorage( storage4 );
cvClearMemStorage( storage5 );
cvClearMemStorage( storage6 );
cvClearMemStorage( storage7 );

// Loop the number of hands found.
for( i = 0; i < (handsO ? handsO->total : 0); i++ )
{
    // Create a new rectangle for drawing the hand
    CvRect* r = (CvRect*)cvGetSeqElem( handsO, i );

    // Find the dimensions of the hand,and scale it if necessary
    pt1.x = r->x*scale;
    pt2.x = (r->x+r->width)*scale;
    pt1.y = r->y*scale;
    pt2.y = (r->y+r->height)*scale;

    /////////////////////  start hand contour detection////////////////////////

    // after finding the hand set it as the area of intrest of the image so all of the functions after that will apply only to that area
    cvSetImageROI(Rhand, cvRect(r->x*scale, r->y*scale, r->width*scale, r->height*scale));
    /*
    / prepare the image to the findContour function
    / 1- convert it to gray
    / 2- threshhold it
    / 3- find the edge
    */
    cvShowImage( "gray hand", Rhand);
    cvThreshold( Rhand, Rhand, 1, 255, CV_THRESH_BINARY );
    cvShowImage( "Threshold hand", Rhand);
    cvCanny(Rhand, Rhand, 1, 3, 5);
    cvShowImage( "Edge hand", Rhand);

    /*
    // cloasing after threshold to test if it will be a beter result 
    IplConvKernel* kernel = 0;
    kernel = cvCreateStructuringElementEx(5,5,0,0, CV_SHAPE_RECT);
    cvDilate(Rhand,Rhand,kernel,1);
    cvErode(Rhand,Rhand,kernel,1);
    */

    // find all contour  in the image
    cvFindContours(Rhand,storage4,&contours,sizeof(CvContour),CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE,cvPoint(0,0));

//  printf("\ncontour num%d",contours->total);
    // find the beggest contour and make it as the hand by comaring the area of each contour
    double area=0,biggestArea=0;
    while(contours)
    {
        area = fabs( cvContourArea( contours, CV_WHOLE_SEQ ) );
        //printf("\n\\\\\\\\\\\\\\\\\\\\\%f",area);

        if ( area > biggestArea) 
        {
        biggestArea = area; 
        hand_contour = contours;
        //printf("\n\\\\\\\\\\\\\\\\\\\\biggest\\\\\\\\\\\\\\%d",hand_contour->total);
        };

        contours  =  contours->h_next;
    }

    cvWaitKey(0);       

    if(hand_contour)
    {

        hand_contour = cvApproxPoly( hand_contour, sizeof(CvContour), storage7, CV_POLY_APPROX_DP, 3, 1 );
        CvRect rect = cvBoundingRect(hand_contour, 1 );
        CvBox2D box = cvMinAreaRect2( hand_contour, storage6 );
        //draw the rectangle arround the contour
        cvRectangle( img, cvPoint(rect.x, rect.y + rect.height), cvPoint(rect.x + rect.width, rect.y), CV_RGB(255, 255, 0), 1, 8, 0 );

        // preparing to detect the finger and compute/ draw them
        CvSeq* hull = cvConvexHull2( hand_contour, 0, CV_CLOCKWISE, 0 );
        int numOfHull =hull->total;
        CvPoint*  hullPoints;
        hullPoints = ( CvPoint *)malloc((hull->total)*sizeof(CvSeq));
        cvCvtSeqToArray(hull,hullPoints);           

        CvSeq* defect = cvConvexityDefects( hand_contour, hull, storage5 );
        int numOfdefect =defect->total;
        CvConvexityDefect* defectArray;
        defectArray = (CvConvexityDefect*)malloc(sizeof(CvConvexityDefect)*numofdefect);  
        cvCvtSeqToArray(defect,defectArray); 

        /*int h1,h2;
        for(i=0; i<numofHull-1; i++)  
        { 
            h1=hull[i];
            h2=hull[i+1];
            cvLine(img, defectArray[h1],defectArray[h2],CV_RGB(255,255,255),1, CV_AA, 0 );  
        }
        int h3=hull[numofHull-1],h4=hull[0];
        cvLine(img, defectArray[h3],defectArray[h4],CV_RGB(255,255,255),1, CV_AA, 0 );  
       // Free memory.            
       free(defectArray);  
       free(hull);  */

       int m=10;
        //cvPolyLine(img,&hullPoints,&m,CV_RGB( 0, 0, 100),1,8,0);
        //cvPolyLine( img, &hullPoints, &m, 2, 0, CV_RGB(0,0,100),10, CV_AA, 0);

        cvCircle( img, cvPoint(pt1.x, pt1.y), 3, CV_RGB(255, 128, 0), 3, 8, 0 );    
        cvCircle( img, cvPoint(box.center.x, box.center.y), 3, CV_RGB(75, 243, 243), 1, 8, 0 );
        cvEllipse( img, cvPoint(pt1.x, pt1.y), cvSize(box.size.height/2, box.size.width/2), box.angle, 0, 360, CV_RGB(220, 0, 120), 2, 8, 0 );
        cvDrawContours( Rhand, hand_contour,  CV_RGB( 0, 200, 100), CV_RGB( 100, 0, 0), 1, 1, 8, cvPoint(pt1.x,pt1.y));
        cvDrawContours( img, hand_contour,  CV_RGB( 0, 200, 100), CV_RGB( 100, 0, 0), 1, 1, 8, cvPoint(pt1.x,pt1.y));
        cvShowImage( "Rhand after draw contour", Rhand);
        cvShowImage( "img After draw contour", img);

        cvResetImageROI(Rhand);
        ///////////////////// End hand contour detection////////////////////////
}
// Draw the rectangle in the input image
 cvRectangle( img, pt1, pt2, CV_RGB(0,255,0), 3, 8, 0 );
}
cvClearSeq(handsO);
}

0 Stimmen

Sie können davon ausgehen, dass die Anzahl der Finger einer Hand fünf beträgt. Mit diesem Code können Sie sehr genau rechnen: int CountFingers(cv::Mat& img) { return 5; }

1voto

RyanfaeScotland Punkte 1151

Ich bin mir des Codes nicht sicher, da ich das gerade erst lerne, aber da cvConvexityDefect die Tiefe angibt, könnte man alle Defekte durchgehen und prüfen, ob dieser Wert innerhalb der Länge liegt, die man von der Fingerspitze bis zur Hand erwarten würde. Sie müssen sich Ihre Hand ansehen und herausfinden, wie viele Defekte es gibt, je nachdem, wie viele Finger Sie sehen können.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X