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

BGS ライブラリを試してみてください。私は以前に使用し、気に入っています。ここから入手できます: http://code.google.com/p/bgslibrary/

于 2013-08-03T15:46:13.330 に答える
0

私があなたを正しく理解しているかどうかはわかりませんが、以下を追加する必要があると思います:

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

GetThresholdedImage でノイズを減らします。でもやはりopencvのcv::Matオブジェクトを使った方がいいと思います;)

于 2013-01-22T14:51:24.950 に答える