如何在MoG2中禁用阴影检测

时间:2016-04-23 11:01:08

标签: c++ opencv background-subtraction mog

我使用C ++和Opencv 2.3.1进行背景扣除。我已经多次尝试更改Mog2的参数以禁用阴影检测功能,我也试过了其他人在互联网上建议的内容。但是,阴影检测仍然有效。

你可以告诉我如何禁用它吗? 请参阅示例代码和生成的掩码。

  //opencv
#include < opencv2/opencv.hpp>
#include < opencv2/core/core.hpp>
#include < opencv2/highgui/highgui.hpp>
#include < opencv2/video/background_segm.hpp>
#include < opencv2/imgproc/imgproc.hpp>
#include < opencv2/video/video.hpp>

//C
 #include <stdio.h>
 //C++
#include <iostream>
#include <sstream>

using namespace cv;
using namespace std;

// Global variables
Mat frame; //current frame
Mat fgMaskMOG2; //fg mask fg mask generated by MOG method
Ptr<BackgroundSubtractor> pMOG2; //MOG Background subtractor
int keyboard; //input from keyboard

//new variables
int history = 1250;
float varThreshold = 16;
bool bShadowDetection = true;

/*
//added to remove the shadow
unsigned char nShadowDetection = 0;
float fTau = 0.5;
//static const unsigned char nShadowDetection =( unsigned char)0;
 */
    // Function Headers 
   void help();
   void processImages(char* firstFrameFilename);

 void help()
{
cout
   << "This program shows how to use background subtraction methods provided   by "  << endl
  << " OpenCV. You can process  images (-img)."                                     << endl                                                                      
    << "Usage:"                                                                     << endl
   << "./bs -img <image filename>}"                                                << endl
   << "for example: ./bs -img /data/images/1.png"                                  << endl
   << endl;
  }

// morphological operation

void morphOps(Mat &thresh){

   //create structuring element that will be used to "dilate" and "erode"   image.
   //the element chosen here is a 3px by 3px rectangle

   Mat erodeElement = getStructuringElement( MORPH_RECT,Size(2,2)); //3x3
   //dilate with larger element so make sure object is nicely visible
   Mat dilateElement = getStructuringElement( MORPH_RECT,Size(1,1)); //8x8

  erode(thresh,thresh,erodeElement);
  erode(thresh,thresh,erodeElement);


    dilate(thresh,thresh,dilateElement);
    dilate(thresh,thresh,dilateElement);

}


// main function

int main(int argc, char* argv[])
{

 //print help information
 help();

 //check for the input parameter correctness
 if(argc != 3) {
    cerr <<"Incorret input list" << endl;
    cerr <<"exiting..." << endl;
    return EXIT_FAILURE;
 }

  //create GUI windows
  namedWindow("Frame");
  namedWindow("FG Mask MOG2 ");

 //create Background Subtractor objects
 //pMOG2 = new BackgroundSubtractorMOG2();
  pMOG2 = new BackgroundSubtractorMOG2( history,   varThreshold,     bShadowDetection);
//BackgroundSubtractorMOG2(int history,  float varThreshold, bool   bShadowDetection=1);
    if(strcmp(argv[1], "-img") == 0) {
    //input data coming from a sequence of images
    processImages(argv[2]);
 }
 else {
    //error in reading input parameters
    cerr <<"Please, check the input parameters." << endl;
    cerr <<"Exiting..." << endl;
    return EXIT_FAILURE;
 }
 //destroy GUI windows
 destroyAllWindows();
 return EXIT_SUCCESS;
}

 //function processImages

 void processImages(char* fistFrameFilename) {
  //read the first file of the sequence
  frame = imread(fistFrameFilename);
  if(frame.empty()){
     //error in opening the first image
     cerr << "Unable to open first image frame: " << fistFrameFilename <<   endl;
     exit(EXIT_FAILURE);

 //current image filename
 string fn(fistFrameFilename);
 //read input data. ESC or 'q' for quitting
  while( (char)keyboard != 'q' && (char)keyboard != 27 ){
     //update the background model
     pMOG2->operator()(frame, fgMaskMOG2,-1);
     //get the frame number and write it on the current frame
     size_t index = fn.find_last_of("/");
     if(index == string::npos) {
        index = fn.find_last_of("\\");
     }
    size_t index2 = fn.find_last_of(".");
    string prefix = fn.substr(0,index+1);
    string suffix = fn.substr(index2);
    string frameNumberString = fn.substr(index+1, index2-index-1);
    istringstream iss(frameNumberString);
    int frameNumber = 0;
    iss >> frameNumber;
    rectangle(frame, cv::Point(10, 2), cv::Point(100,20),
              cv::Scalar(255,255,255), -1);
    putText(frame, frameNumberString.c_str(), cv::Point(15, 15),
            FONT_HERSHEY_SIMPLEX, 0.5 , cv::Scalar(0,0,0));
    //show the current frame and the fg masks
    imshow("Frame", frame);
    morphOps(fgMaskMOG2);
    imshow("FG Mask MOG2 ", fgMaskMOG2);
    //get the input from the keyboard
    keyboard = waitKey(1);
    //search for the next image in the sequence
    ostringstream oss;
    oss << (frameNumber + 1);
    string nextFrameNumberString = oss.str();
    string nextFrameFilename = prefix + nextFrameNumberString + suffix;
    //read the next frame
    frame = imread(nextFrameFilename);
    if(frame.empty()){
        //error in opening the next image in the sequence
        cerr << "Unable to open image frame: " << nextFrameFilename << endl;
        exit(EXIT_FAILURE);
    }
    //update the path of the current frame
    fn.assign(nextFrameFilename);

    // save subtracted images
    string imageToSave =("output_MOG_" +  frameNumberString + ".png");
    bool saved = imwrite(  "D:\\SO\\temp\\" +imageToSave,fgMaskMOG2);
    if(!saved) {
    cerr << "Unable to save " << imageToSave << endl;
       }
}
}

enter image description here}

2 个答案:

答案 0 :(得分:1)

看看the documentation

你的代码

bool bShadowDetection = true;

将其更改为

bool bShadowDetection = false;

编辑: OpenCV 3的BackgroundSubtractorMOG2类具有setShadowValue (int value)功能来设置阴影的灰度值。 将灰色设置为零将删除阴影。

答案 1 :(得分:0)

这取决于您真正想要看到的内容 - 如果您想将阴影与细分分开:

bool bShadowDetection = true; 并使用 cv::threshold(Mask,Mask,254,255,cv::THRESH_BINARY);MOG2->apply()之后

你的图像中只有{255}的部分

并且为了恢复这个... ...