2013-01-21 59 views
0

美好的一天。我是OpenCV的新手,現在我嘗試使用顏色跟蹤和背景減法來進行指尖檢測。我的顏色跟蹤部分工作,但我不知道如何減去背景,只留下指尖。OpenCV指尖檢測

這是我的代碼。

#include <opencv2/opencv.hpp> 

#include <stdio.h> 
#include <iostream> 

using namespace std; 

IplImage* GetThresholdedImage(IplImage* img, CvScalar& lowerBound, CvScalar& upperBound) 
{ 
    // Convert the image into an HSV image 
    IplImage* imgHSV = cvCreateImage(cvGetSize(img), 8, 3); 
    cvCvtColor(img, imgHSV, CV_BGR2HSV); 

    IplImage* imgThreshed = cvCreateImage(cvGetSize(img), 8, 1); 

    cvInRangeS(imgHSV, lowerBound, upperBound, imgThreshed); 

    cvReleaseImage(&imgHSV); 
    return imgThreshed; 
} 



int main() 
{ 
    int lineThickness = 2; 

    CvScalar lowerBound = cvScalar(20, 100, 100); 
    CvScalar upperBound = cvScalar(30, 255, 255); 

    int b,g,r; 
    lowerBound = cvScalar(0,58,89); 

    upperBound = cvScalar(25,173,229); 

    CvCapture* capture = 0; 
    capture = cvCaptureFromCAM(1); 

    if(!capture) 
    { 
     printf("Could not initialize capturing...\n"); 
     return -1; 
    } 

    cvNamedWindow("video"); 
    cvNamedWindow("thresh"); 

    // This image holds the "scribble" data... 
    // the tracked positions of the object 
    IplImage* imgScribble = NULL; 

    while(true) 
    { 
     IplImage* frame = 0; 
     frame = cvQueryFrame(capture); 

     if(!frame) 
     break; 

     // If this is the first frame, we need to initialize it 
     if(imgScribble == NULL) 
     { 
     imgScribble = cvCreateImage(cvGetSize(frame), 8, 3); 
     } 

     // Holds the thresholded image (tracked color -> white, the rest -> black) 
     IplImage* imgThresh = GetThresholdedImage(frame,lowerBound,upperBound); 

     // Calculate the moments to estimate the position of the object 
     CvMoments *moments = (CvMoments*)malloc(sizeof(CvMoments)); 
     cvMoments(imgThresh, moments, 1); 

     // The actual moment values 
     double moment10 = cvGetSpatialMoment(moments, 1, 0); 
     double moment01 = cvGetSpatialMoment(moments, 0, 1); 
     double area = cvGetCentralMoment(moments, 0, 0); 

     // Holding the last and current positions 
     static int posX = 0; 
     static int posY = 0; 

     int lastX = posX; 
     int lastY = posY; 

     posX = moment10/area; 
     posY = moment01/area; 


     cout << "position = " << posX << " " << posY << endl; 

     // We want to draw a line only if its a valid position 
     if(lastX>0 && lastY>0 && posX>0 && posY>0) 
     { 
     // Draw a yellow line from the previous point to the current point 
     cvLine(imgScribble, cvPoint(posX, posY), cvPoint(lastX, lastY), upperBound, lineThickness); 


     } 


     // Add the scribbling image and the frame... 
     cvAdd(frame, imgScribble, frame); 
     cvShowImage("thresh", imgThresh); 
     cvShowImage("video", frame); 

     int c = cvWaitKey(10); 
     if(c==27) //ESC key 
     { 
     break; 
     } 

     cvReleaseImage(&imgThresh); 
     delete moments; 
    } 

    cvReleaseCapture(&capture); 
    return 0; 
} 

回答

0

我不知道如果我理解你的權利,但我想你應該需要添加以下內容:

cvErode(imgThreshed, imgThreshed, NULL, 1); 
    cvDilate(imgThreshed, imgThreshed, NULL, 1); 
在GetThresholdedImage

,並得到更少的噪聲!但畢竟我認爲它會更好地使用opencv的cv :: Mat對象;)

+0

謝謝。我會研究它。 :) – user1876574