Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot set user parameters in BackgroundSubtractorMOG2

OpenCV library version 2.42. I'd like to set a parameter in BackgroundSubtractorMOG2 object, e.g.

BackgroundSubtractorMOG2 bgr;  

// the following doesn't work because 'nmixtures', 'backgroundRatio' 
// and 'fVarMin' are a protected members.
bgr.nmixtures = 3;   
bgr.backgroundRatio = 0.9;
bgr.fVarMin = 5; 

// the following works 
bgr.set('nmixtures', 3); 

// both of the following lines will give a run-time error 
// `Access violation reading location 0x0000000000000008.`
bgr.set("backgroundRatio", 0.9);  
bgr.set("fVarMin", 5);     

backgroundRatio and fVarMin are parameters that control the algorithm. User should be able to change these parameters according to the documentation.

How can I set the parameters of BackgroundSubtractorMOG2?

EDIT As correctly mentioned in the answer below, this was a bug in OpenCV. The bug was fixed in OpenCV version 2.4.6.

like image 273
Alexey Avatar asked Oct 12 '12 14:10

Alexey


3 Answers

I've just looked OpenCV source code and found interesting initialization in file /modules/video/src/video_init.cpp. Here it is:

CV_INIT_ALGORITHM(BackgroundSubtractorMOG2, "BackgroundSubtractor.MOG2",
    obj.info()->addParam(obj, "history", obj.history);
    obj.info()->addParam(obj, "nmixtures", obj.nmixtures);
    obj.info()->addParam(obj, "varThreshold", obj.varThreshold);
    obj.info()->addParam(obj, "detectShadows", obj.bShadowDetection));

It seems that it's possible to set only these four parameters using method set.

And also take a look at file modules/video/src/bgfg_gaussmix2.cpp, which has a BackgroundSubtractorMOG2 class. It has the following fields:

float fVarInit;
float fVarMax;
float fVarMin;
//initial standard deviation  for the newly generated components.
//It will will influence the speed of adaptation. A good guess should be made.
//A simple way is to estimate the typical standard deviation from the images.
//I used here 10 as a reasonable value

And the value fVarMin (which you want to change) is set to:

fVarMin = defaultVarMin2

in both constructors. Here are all of them:

static const float defaultVarInit2 = 15.0f; // initial variance for new components
static const float defaultVarMax2 = 5*defaultVarInit2;
static const float defaultVarMin2 = 4.0f;

And interesting fact that this value is not used in any other file, so it seems that it's impossible to change it for now. You can post this issue directly to OpenCV bugtracker.

like image 137
ArtemStorozhuk Avatar answered Oct 30 '22 03:10

ArtemStorozhuk


Yes, bgr.set("nmixtures",3); should work. BackgroundSubtractorMOG2 inherits from cv::Algorithm, so you use cv:Algorithm::get and cv::Algorithm::set to access those parameters. Did you try that and it doesn't work?

like image 36
Sassa Avatar answered Oct 30 '22 01:10

Sassa


Since these parameters are protected, a derived class can access them. I made a derived class to set all the necessary parameters.

struct BackgroundModel2ParameterBlock {
int nmixtures;
float backgroundRatio;
float varThresholdGen;
float fVarInit;
float fVarMin;
float fVarMax;
BackgroundModel2ParameterBlock(void) :
  nmixtures(3),
  backgroundRatio(0.6),
  varThresholdGen(6.25),
  fVarInit(256),
  fVarMin(256),
  fVarMax(9e2)
{ }
};

class BackgroundModel2 : public cv::BackgroundSubtractorMOG2 {
private:
  BackgroundModel2ParameterBlock m_param;
};

BackgroundModel2::BackgroundModel2(BackgroundModel2ParameterBlock param):
  BackgroundSubtractorMOG2(),
  m_param(param)
{
  nmixtures = m_param.nmixtures;
  backgroundRatio = m_param.backgroundRatio;
  varThresholdGen = m_param.varThresholdGen;
  fVarInit = m_param.fVarInit;
  fVarMin = m_param.fVarMin;
  fVarMax = m_param.fVarMax;
}
like image 43
DXM Avatar answered Oct 30 '22 01:10

DXM