7

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.

Alexey
  • 5,898
  • 9
  • 44
  • 81

4 Answers4

9

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.

ArtemStorozhuk
  • 8,715
  • 4
  • 35
  • 53
  • Is my issue `http://stackoverflow.com/questions/17284712/error-in-backgroundsubtraction-mog2` is same as this ? –  Jun 27 '13 at 18:54
4

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?

Sassa
  • 3,294
  • 2
  • 28
  • 42
  • `bgr.set("nmixtures",3);` works but `bgr.set("bShadowDetection", false);` doesn't. – Alexey Oct 12 '12 at 15:06
  • How about if you set it in the constructor like [that](http://docs.opencv.org/modules/video/doc/motion_analysis_and_object_tracking.html?highlight=backgroundsubtractormog2#backgroundsubtractormog2-backgroundsubtractormog2). Does this work? – Sassa Oct 12 '12 at 15:12
  • Yeah, I guess the best option is to set all the properties in the constructor. It seems that some of parameters can't be changed even using `cv::Algorithm` interface. http://answers.opencv.org/question/1310/access-to-mog2-parameters-via-algorithm-interface/ – Alexey Oct 12 '12 at 15:15
  • Probably getters and setters are not defined for bShadowDetection. I think that you can use set and get for all the parameters mentioned [here](http://docs.opencv.org/modules/video/doc/motion_analysis_and_object_tracking.html?highlight=backgroundsubtractormog2#backgroundsubtractormog2) – Sassa Oct 12 '12 at 15:16
  • When I do `bgr.set("fVarMin", 5);` (this is one of user defined parameters), the code compiles but I get run a time error. So it doesn't work for some reason.. – Alexey Oct 12 '12 at 15:58
  • Does it get set or not? What does it return using `Algorithm::get`? If it returns 5, it means that it actually works but for some reason that value causes runtime error. If this is the case, it doesn't have anything to do with the setter though. Do you get a runtime on exactly that line? – Sassa Oct 12 '12 at 16:06
  • Don't think it's the value, the code crashes exactly on `bgr.set("fVarMin", 5);` line and the value of `bgr.fVarMin` doesn't change. I tried `bgr.set("fVarMin", (float)5);` but it still crashes. – Alexey Oct 12 '12 at 16:08
  • I haven't read that paper, what does fVarMin represent? Did you try with other values? Does it say anything else, except for runtime error? – Sassa Oct 12 '12 at 16:13
  • The error says `Access violation reading location 0x0000000000000008.` Also crashes for `bgr.set("backgroundRatio", 0.9)`. These are all user configurable parameters and the corresponding values I try to set them to are all within the allowable range (e.g. default value for `bgr.backgroundRatio` is 0.9). – Alexey Oct 12 '12 at 16:20
  • @Alex It may be stupid, but have you tried bgr.set("backgroundRatio", 0.9f); – Sassa Oct 15 '12 at 20:15
  • tried it - no luck. Also tried `bgr.set("backgroundRatio", (float) 0.9)` but it gives the same run-time error. – Alexey Oct 15 '12 at 20:20
2

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;
}
DXM
  • 1,249
  • 1
  • 14
  • 22
1

In android, use algorithm functions: setDouble, setInt, setBool: this works:

mBgMog2 = new BackgroundSubtractorMOG2(mHistory,mMog2Threshold );  
mBgMog2.setInt("nmixtures" , 3);
mBgMog2.setDouble("fVarInit" , 80.0);
mBgMog2.setDouble("fTau" , 0.2);
mBgMog2.setDouble("fVarMin" , 200.0);
mBgMog2.setDouble("fVarMax" , 80.0);
mBgMog2.setBool("detectShadows",false);
Rizier123
  • 58,877
  • 16
  • 101
  • 156
Abe
  • 11
  • 1