2013-06-07 15 views
10

Quello che intendo fare è la seguente:colore monitoraggio oggetto in OpenCV continua a rilevare la pelle

fissare un oggetto colorato. Tracciabilità attraverso i fotogrammi video utilizzando l'approccio istogramma-retroproiezione con camshift. Io uso il seguente codice e finisce sempre per rilevare la pelle. Capisco che sto facendo un errore terribilmente semplice. Sarebbe utile se qualcuno potesse indicarlo.

//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:

eseguire controllo la parte modificata del codice, in cui durante la creazione dell'istogramma sto usando valore della tonalità della maschera nell'intervallo 0-180. Se utilizzo l'intervallo ridotto 80-100, ottengo i valori garbage in componenti e curr_box.

UPDATE: uscita immagini

Questo è il blob verde rilevato inizialmente e deve essere monitorato durante la registrazione.

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

Questo è ciò che accade. Il blob verde è completamente oscurato nell'immagine della maschera e invece viene tracciata la pelle.

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

+0

Non stai aggiustando il colore per tracciare il colore della pelle? Sembra un po 'così. – Nallath

+0

Potresti fornire alcuni campioni? Ad esempio il tuo video di input e il risultato del monitoraggio. – cyriel

+0

@Nallath: Suppongo che il colore della pelle abbia un valore H compreso tra 0 e 20 (correggimi se ho torto). –

risposta

6

Innanzitutto scuse per tutta la confusione. C'è un bug molto stupido nel codice. Sto clonando la cornice originale dopo aver posizionato un rettangolo rosso pieno sopra di essa.

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); 

Quindi, l'istogramma creato è sempre per il colore rosso. La soluzione è banale.

Problemi correlati