0

再会。我是 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;
}
4

2 回答 2

0

我不知道我是否理解你,但我认为你应该需要添加以下内容:

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

在 GetThresholdedImage 中并获得更少的噪音!但毕竟我认为你最好使用 opencv 的 cv::Mat 对象;)

于 2013-01-22T14:51:24.950 回答
0

试试 BGS 库,我以前用过,很喜欢。你可以在这里得到它:http ://code.google.com/p/bgslibrary/

于 2013-08-03T15:46:13.330 回答