2014-04-02 1 views
1

실시간 모션 감지 프로그램을하고 있습니다. 배경 차감 방법을 사용한 후에는 다른 이미지에 윤곽이 많이 생겼습니다. 나는이 윤곽선을 서로 병합하거나 큰 윤곽선에 모든 윤곽을 포함시킬 수있는 방법이 있는지 묻고 싶습니다.(opencv) 등고선 병합하기

지금은
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; 

가}

답변

0

나는 비슷한 문제를 건너 왔어요 여기에있다. 제 경우에는 빈 시퀀스를 만들고 각 윤곽선의 점으로 채 웁니다. 그런 다음 그 시퀀스로 경계 타원을 맞추 었습니다. 다음은 내 코드 세그먼트 ...이 도움이

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

의 희망입니다.

4

시도해 보셨습니까?

   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. 일부 응용 프로그램의 경우 convexHull()보다는 approxPoly()를 사용하는 것이 더 좋습니다. 그냥 둘 다 시도해보십시오.

+0

이 답변은 정답으로 표시되어야합니다. – Croolman

+0

파이썬에서 이와 같은 작업을했으며 효과가있었습니다. –

+0

@HamzaAbbad에서 파이썬 코드를 제공 할 수 있습니까? – MOHRE