2013-06-07 3 views
10

Was ich vorhabe zu tun ist wie folgt:Farbe Objektverfolgung in OpenCV hält die Haut

Fix ein farbiges Objekt. Verfolgen Sie es über Video-Frames mit Histogramm-Rückprojektion Ansatz mit Camshift. Ich benutze den folgenden Code und es endet immer die Haut zu erkennen. Ich verstehe, dass ich einen furchtbar einfachen Fehler mache. Es wäre hilfreich, wenn jemand darauf hinweisen könnte.

//I have included only the integral parts of code. There are no compilation errors. 

    int lowerH =80, upperH =100, lowerS =80, upperS =255, lowerV =80, upperV =255; 

    CvScalar output_min =cvScalar(lowerH, lowerS, lowerV, 0); //Color Track 
    CvScalar output_max =cvScalar(upperH, upperS, upperV, 0); 

    CvScalar output_min2 =cvScalar(0, lowerS, lowerV, 0); //Color Track 
    CvScalar output_max2 =cvScalar(180, upperS, upperV, 0); 

    while(true){ 
     frame =cvQueryFrame(capture); 

     cvCvtColor(frame, output, CV_BGR2HSV); 
     cvInRangeS(output, output_min, output_max, output_mask); 

     blobs =CBlobResult(output_mask, NULL, 0); 
     blobs.Filter(blobs, B_EXCLUDE, CBlobGetArea(), B_LESS, 35); 

     int num_blobs =blobs.GetNumBlobs(); 
     for(int i=0; i<num_blobs;++i){ 
      currentBlob = blobs.GetBlob(i);     
      sortedBlobs.push_back(currentBlob); 
     } 

     if(num_blobs){ 
      sort(sortedBlobs.begin(), sortedBlobs.end(), local::sortBlobs); 
      CvRect blobRect =sortedBlobs[0].GetBoundingBox(); 

      initX =blobRect.x; 
      initY =blobRect.y; 
      initWidth =blobRect.width; 
      initHeight =blobRect.height; 
      initFrame =cvCloneImage(frame); 
     } 

      int c=cvWaitKey(40); 
     if((char)c ==27)break; 
    } 

    CvRect selection; 
    selection.x = initX; 
    selection.y = initY; 
    selection.width = initWidth; 
    selection.height = initHeight; 

    CvHistogram *hist; 
    int hist_bins = 30;   
    float hist_range[] = {0, 180}; 
    float* range = hist_range; 
    hist = cvCreateHist(1, &hist_bins, CV_HIST_ARRAY, &range, 1);   

    cvCvtColor(initFrame, output, CV_BGR2HSV); 
    cvInRangeS(output, output_min2, output_max2, output_mask); 
    cvSplit(output, hue, 0, 0, 0); 

    cvSetImageROI(hue, selection); 
    cvSetImageROI(output_mask, selection); 

    cvCalcHist(&hue, hist, 0, output_mask); 
    float max_val = 0.f; 
    cvGetMinMaxHistValue(hist, 0, &max_val, 0, 0); 
    cvConvertScale(hist->bins, hist->bins, 
       max_val ? 255.0/max_val : 0, 0); 

    cvResetImageROI(hue); 
    cvResetImageROI(output_mask); 


    CvBox2D curr_box; 
    CvRect prev_rect =selection; 
    CvConnectedComp components; 
    bool rectFlag =false; 
    CvPoint Pt =cvPoint(0,0), prevPt =cvPoint(0,0); 
    int clearCounter =0; 
    while(true){ 
     frame =cvQueryFrame(capture); 
     if(!frame)break; 

     cvCvtColor(frame, output, CV_BGR2HSV); 
     cvInRangeS(output, output_min2, output_max2, output_mask); 
     cvSplit(output, hue, 0, 0, 0); 

     cvCalcBackProject(&hue, prob, hist); 
     cvAnd(prob, output_mask, prob, 0); 

     cvCamShift(prob, prev_rect, cvTermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 20, 1), &components, &curr_box); 

     prev_rect = components.rect; 
     curr_box.angle = -curr_box.angle; 

     cvEllipseBox(frame, curr_box, CV_RGB(255,0,0), 3, CV_AA, 0); 

     int c=cvWaitKey(40); 
     if((char)c ==27)break; 
    } 

EDIT:

Sie das bearbeitete Teil des Codes überprüfen, wobei während des Histogramms zu schaffen Ich bin mit Farbtonwert für die Maske im Bereich 0-180. Wenn ich den reduzierten Bereich 80-100 verwende, erhalte ich Müllwerte in Komponenten und curr_box.

UPDATE: Ausgabe Bilder

Dies ist der grüne Klecks zunächst erkannt und sollte während der Aufnahme verfolgt werden.

This is the green blob detected initially and should be tracked throughout the recording

Dies ist, was passiert. Der grüne Blob wird im Maskenbild vollständig ausgeblendet und stattdessen wird die Haut nachverfolgt.

This is what happens. The green blob is completely blacked out in the mask image and instead the skin is tracked

+0

Fixieren Sie nicht die Farbe, um Hautfarbe zu verfolgen? Es scheint irgendwie so. – Nallath

+0

Können Sie einige Proben zur Verfügung stellen? Zum Beispiel Ihr eingegebenes Video und das Ergebnis des Trackings. – cyriel

+0

@Nallath: Ich nehme an, Hautfarbe hat H-Wert im Bereich 0-20 (korrigieren Sie mich, wenn ich falsch liege). –

Antwort

6

Zunächst einmal Entschuldigungen für die ganze Verwirrung. Es gibt einen sehr dummen Fehler im Code. Ich klicke den Originalrahmen, nachdem ich ein gefülltes rotes Rechteck darauf gelegt habe.

CvPoint pt1, pt2; 
    pt1.x = blobRect.x; 
    pt1.y = blobRect.y; 
    pt2.x = blobRect.x + blobRect.width; 
    pt2.y = blobRect.y + blobRect.height; 

    cvRectangle(frame, pt1, pt2, cvScalar(0, 0, 255, 0), CV_FILLED, 8, 0); 

    initX =blobRect.x; 
    initY =blobRect.y; 
    initWidth =blobRect.width; 
    initHeight =blobRect.height; 
    initFrame =cvCloneImage(frame); 

Daher ist das Histogramm, das erstellt wird, immer für die rote Farbe. Die Lösung ist trivial.