Cannot set user parameters in BackgroundSubtractorMOG2
Asked Answered
C

4

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.

Chairmanship answered 12/10, 2012 at 14:17 Comment(2)
In earlier versions of OpenCV nmixtures and other parameters used to be public but it was changed in version 2.4.Chairmanship
posted the question on OpenCV board. Still no answer.Chairmanship
T
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.

Tootsy answered 15/10, 2012 at 22:28 Comment(1)
Is my issue http://stackoverflow.com/questions/17284712/error-in-backgroundsubtraction-mog2 is same as this ?Undulatory
H
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?

Heimlich answered 12/10, 2012 at 14:57 Comment(11)
bgr.set("nmixtures",3); works but bgr.set("bShadowDetection", false); doesn't.Chairmanship
How about if you set it in the constructor like that. Does this work?Heimlich
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. answers.opencv.org/question/1310/…Chairmanship
Probably getters and setters are not defined for bShadowDetection. I think that you can use set and get for all the parameters mentioned hereHeimlich
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..Chairmanship
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?Heimlich
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.Chairmanship
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?Heimlich
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).Chairmanship
@Alex It may be stupid, but have you tried bgr.set("backgroundRatio", 0.9f);Heimlich
tried it - no luck. Also tried bgr.set("backgroundRatio", (float) 0.9) but it gives the same run-time error.Chairmanship
P
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;
}
Proconsul answered 21/3, 2013 at 21:31 Comment(0)
G
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);
Gastro answered 18/12, 2014 at 11:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.