【问题标题】:(opencv) merge contours together(opencv)将轮廓合并在一起
【发布时间】:2014-05-13 03:38:07
【问题描述】:

我正在做一个实时运动检测程序。我发现在我使用背景减法后,我的不同图像中有很多轮廓。我想问有没有什么方法可以将这些轮廓合并在一起,或者让一个更大的矩形包含所有的轮廓?

这个案子我已经做完了
http://singhgaganpreet.files.wordpress.com/2012/07/motioncolour.jpg
我的代码在这里

#include <iostream>
#include <OpenCV/cv.h>
#include <OPenCV/highgui.h>

using namespace cv;
using namespace std;

CvRect rect;
CvSeq* contours = 0;
CvMemStorage* storage = NULL;
CvCapture *cam;
IplImage *currentFrame, *currentFrame_grey, *differenceImg, *oldFrame_grey;

bool first = true;

int main(int argc, char* argv[])
{
   //Create a new movie capture object.
   cam = cvCaptureFromCAM(0);

   //create storage for contours
   storage = cvCreateMemStorage(0);

   //capture current frame from webcam
   currentFrame = cvQueryFrame(cam);

   //Size of the image.
   CvSize imgSize;
   imgSize.width = currentFrame->width;
   imgSize.height = currentFrame->height;

   //Images to use in the program.
   currentFrame_grey = cvCreateImage( imgSize, IPL_DEPTH_8U, 1);                           

   while(1)
   {
          currentFrame = cvQueryFrame( cam );
          if( !currentFrame ) break;

          //Convert the image to grayscale.
          cvCvtColor(currentFrame,currentFrame_grey,CV_RGB2GRAY);

          if(first) //Capturing Background for the first time
          {
                 differenceImg = cvCloneImage(currentFrame_grey);
                 oldFrame_grey = cvCloneImage(currentFrame_grey);
                 cvConvertScale(currentFrame_grey, oldFrame_grey, 1.0, 0.0);
                 first = false;
                 continue;
          }

          //Minus the current frame from the moving average.
          cvAbsDiff(oldFrame_grey,currentFrame_grey,differenceImg);

          //bluring the differnece image
          cvSmooth(differenceImg, differenceImg, CV_BLUR);             

          //apply threshold to discard small unwanted movements
          cvThreshold(differenceImg, differenceImg, 25, 255, CV_THRESH_BINARY);

          //find contours
          cvFindContours( differenceImg, storage, &contours );

          //draw bounding box around each contour
          for(; contours!=0; contours = contours->h_next)
          {
                 rect = cvBoundingRect(contours, 0); //extract bounding box for current contour

                 //drawing rectangle
                 cvRectangle(currentFrame,                  
                              cvPoint(rect.x, rect.y),    
                              cvPoint(rect.x+rect.width, rect.y+rect.height),
                              cvScalar(0, 0, 255, 0),
                              2, 8, 0);                 
          }

          //display colour image with bounding box
          cvShowImage("Output Image", currentFrame);

          //display threshold image
          cvShowImage("Difference image", differenceImg);

          //New Background
          cvConvertScale(currentFrame_grey, oldFrame_grey, 1.0, 0.0);

          //clear memory and contours
          cvClearMemStorage( storage );
          contours = 0;

          //press Esc to exit
          char c = cvWaitKey(33);
          if( c == 27 ) break;

   }

   // Destroy the image & movies objects
   cvReleaseImage(&oldFrame_grey);
   cvReleaseImage(&differenceImg);
   cvReleaseImage(&currentFrame);
   cvReleaseImage(&currentFrame_grey);
   //cvReleaseCapture(&cam);

   return 0;

}

【问题讨论】:

    标签: merge contour


    【解决方案1】:

    你试过了吗?

    std::vector<cv::Point> points;
    points.insert(points.end(), contour1.begin(), contour1.end());
    points.insert(points.end(), contour2.begin(), contour2.end());
    convexHull(cv::Mat(points), contour);
    

    PS。对于某些应用程序,使用 approxPoly() 可能比 convexHull() 更好。两个都试试。

    PPS。尝试用高斯平滑得到的轮廓。这也很有帮助。

    【讨论】:

    • 不,我们切换到 c++
    【解决方案2】:

    我遇到了类似的问题。在我的例子中,我创建了一个空序列,然后用每个轮廓的点填充它,之后我用该序列拟合了一个边界椭圆。 这是我的代码段...

    CvMemStorage *storage = cvCreateMemStorage ();
    CvMemStorage *storage1 = cvCreateMemStorage ();
    CvSeq *contours = 0;
    
    //find contour in BInv
    cvFindContours (BInv, storage, &contours, sizeof(CvContour), CV_RETR_LIST,CV_CHAIN_APPROX_NONE ,cvPoint(0,0)); 
    
    //creating empty sequence of CvPoint
    CvSeq* seq = cvCreateSeq(CV_SEQ_ELTYPE_POINT/*| CV_SEQ_KIND_SET | CV_SEQ_FLAG_SIMPLE*/,sizeof(CvSeq),sizeof(CvPoint),storage1);
    
    //populating seq with all contours
    for(; contours!=0; contours = contours->h_next)
      for(int i=0;i<contours->total;i++)
         {  
             CvPoint* p;
            p = (CvPoint*)cvGetSeqElem (contours, i );
            cvSeqPush(seq,p);   
          }
    
    //bounding box and drawing
    CvBox2D bbox=cvMinAreaRect2(seq, NULL );
    cvEllipseBox(color,bbox,cvScalarAll(0),5,8,0);
    

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-18
      • 2011-10-03
      • 2021-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-12
      • 2022-01-10
      相关资源
      最近更新 更多