2013-03-02 1 views
0

전경 물체를 감지하기 위해 비디오 처리 프로젝트를 진행 중입니다. 아래는 전경과 배경을 분리하는 데 사용되는 코드의 일부입니다.배경 빼기 개선

#include "opencv2/core/core.hpp" 
#include "opencv2/video/background_segm.hpp" 
#include "opencv2/highgui/highgui.hpp" 
#include <stdio.h> 

using namespace std; 
using namespace cv; 


//this is a sample for foreground detection functions 
int main(int argc, const char** argv) 
{ 


    VideoCapture cap; 
    bool update_bg_model = true; 

    cap.open(0); 


    if(!cap.isOpened()) 
    { 
     printf("can not open camera or video file\n"); 
     return -1; 
    } 

    namedWindow("image", CV_WINDOW_NORMAL); 
    namedWindow("foreground mask", CV_WINDOW_NORMAL); 
    namedWindow("foreground image", CV_WINDOW_NORMAL); 
    namedWindow("mean background image", CV_WINDOW_NORMAL); 

    BackgroundSubtractorMOG2 bg_model; 
    Mat img, fgmask, fgimg; 

    for(;;) 
    { 
     cap >> img; 

     if(img.empty()) 
      break; 

     if(fgimg.empty()) 
      fgimg.create(img.size(), img.type()); 

     //update the model 
     bg_model(img, fgmask, update_bg_model ? -1 : 0); 

     fgimg = Scalar::all(0); 
     img.copyTo(fgimg, fgmask); 

     Mat bgimg; 
     bg_model.getBackgroundImage(bgimg); 

     imshow("image", img); 
     imshow("foreground mask", fgmask); 
     imshow("foreground image", fgimg); 
     if(!bgimg.empty()) 
      imshow("mean background image", bgimg); 

     char k = (char)waitKey(30); 
     if(k == 27) break; 
     if(k == ' ') 
     { 
      update_bg_model = !update_bg_model; 
      if(update_bg_model) 
       printf("Background update is on\n"); 
      else 
       printf("Background update is off\n"); 
     } 
    } 

    return 0; 
} 

전경 마스크 창에서 실제 전경 오브젝트와 함께 많은 노이즈가 발생합니다. 또한 fulll 객체는 전경으로 인식됩니다. 전경 오브젝트를 사각형으로 묶어야합니다. Wil BoundRect()는 전경 마스크에서 윤곽선을 그리면 작업을 수행합니까? ... 윤곽선을 찾는 동안 (findcontour()) 전달할 가장 권장되는 매개 변수는 무엇입니까? BoundRect 함수 ... 미리 감사드립니다.

+0

이미지에 노이즈가있는 경우 (모든 비디오 에서처럼) 가장 간단한 해결책은 일종의 가우시안 블러를 실행하는 것입니다. 나는이 부분을 이해하지 못했다 : "또한 fulll 객체는 전경으로 인식된다"는 의미는 무엇입니까? 그것에 대해 좀 더 명확히해야합니다. – OopsUser

+0

이 뜻은 다음과 같습니다. http://answers.opencv.org/upfiles/13623024413088434.png – hunter

답변

2

답변하기에는 너무 늦었지만 다른 사람에게 도움이되기를 바랍니다.

픽셀의 완벽한 방식으로 비디오의 배경에서 전경을 분리하면 (배경에 대한 제약없이) 매우 어려운 문제입니다. 이 분야에 많은 연구가 진행되었지만 여전히 범위가 있습니다. 그래서 가우시안의 단순한 혼합은 (BackgroundSubtractorMOG2에서 사용 된 것처럼) 매우 정확한 결과를 제공하지 못할 수도 있습니다. MOG의 결정은 컬러 큐를 기반으로하고 배경의 일부 픽셀이 그것에 의해 만들어진 가우스 모델에 맞을 가능성이 있기 때문에 노이즈는 거의 불가피합니다.

전경처럼 보이는이 픽셀들은 효과적으로 변화를 나타냅니다. 따라서 배경 모델의 학습 속도를 고치면 움직이는 픽셀을 면밀히 추적 할 수 있습니다. 배경이 상당히 정적이라는 가정하에 작업 할 수있는 경우 움직이는 픽셀은 사용자의 전경을 나타내므로 문제를 어느 정도 해결할 수 있습니다.

또한 OpenCV에서 BackgroundSubtractorGMG 기능을 사용하는 것이 좋습니다. 이 함수는 처음 몇 (숫자를 설정할 수 있음) 프레임에서 배경 모델을 학습합니다. 가능하다면 처음 몇 개의 프레임을 전경으로 보자. 괜찮은 결과를 얻을 수 있습니다.