混合高斯模型:opencv中MOG2的代码结构梳理
/* 头文件:OurGaussmix2.h */ #include "opencv2/core/core.hpp" #include <list> #include"cv.h" using namespace cv;//InputArray 等的定义在cv里面 namespace ourGaussmix { class BackgroundSubtractor: public cv::Algorithm { public: virtual ~BackgroundSubtractor(); virtual void operator()(InputArray _image, OutputArray _fgmask, double learningRate); virtual void getBackgroundImage(OutputArray backgroundImage,OutputArray backgroundImageslow) const; }; class OurBackgroundSubtractorMOG2 : public BackgroundSubtractor { public: OurBackgroundSubtractorMOG2(); OurBackgroundSubtractorMOG2(int history, float varThreshold, bool bShadowDetection=true); virtual ~OurBackgroundSubtractorMOG2(); virtual void operator()(InputArray _image, OutputArray _fgmask, double learningRate); virtual void getBackgroundImage(OutputArray backgroundImage,OutputArray backgroundImageslow) const; virtual void initialize(Size frameSize, int frameType); }; } /* cpp文件 */ namespace ourGaussmix { /**************************** static const 类型的默认参数 *****************************/ struct GaussBGStatModel2Params { //存储参数 }; struct GMM { float weight; float variance; }; /***基类中的虚函数都设为空的***/ BackgroundSubtractor::~BackgroundSubtractor() {} void BackgroundSubtractor::operator()(InputArray _image, OutputArray _fgmask, double learningRate) { } void BackgroundSubtractor::getBackgroundImage(OutputArray,OutputArray) const { } static CV_INLINE bool detectShadowGMM(const float* data, int nchannels, int nmodes,const GMM* gmm, const float* mean, float Tb, float TB, float tau) { /*阴影检测函数内容*/ } /*定义一个结构体用来执行OurBackgroundSubtractorMOG2*/ struct MOG2Invoker { /*C++中结构体是一个特殊的类 下面的是构造函数*/ MOG2Invoker(const Mat& _src, Mat& _dst, GMM* _gmm, float* _mean, uchar* _modesUsed, int _nmixtures, float _alphaT, float _Tb, float _TB, float _Tg, float _varInit, float _varMin, float _varMax, float _prune, float _tau, bool _detectShadows, uchar _shadowVal) { /*给结构体的参数赋值*/ } void operator()(const BlockedRange& range) const { /*混合高斯模型参数的更新*/ } }; OurBackgroundSubtractorMOG2::OurBackgroundSubtractorMOG2() { /*默认构造函数赋值 全部赋予默认值*/ } OurBackgroundSubtractorMOG2::OurBackgroundSubtractorMOG2(int _history, float _varThreshold, bool _bShadowDetection) { /*构造函数赋值 部分自选 其他默认值*/ } OurBackgroundSubtractorMOG2::~OurBackgroundSubtractorMOG2() { } void OurBackgroundSubtractorMOG2::initialize(Size _frameSize, int _frameType) { /*初始化函数 分配内存*/ //bgmodel.create( 1, frameSize.height*frameSize.width*nmixtures*(2 + nchannels), CV_32F ); //bgmodelUsedModes.create(frameSize,CV_8U); //bgmodelUsedModes = Scalar::all(0); } void OurBackgroundSubtractorMOG2::operator()(InputArray _image, OutputArray _fgmask, double learningRate) { /*判断是否初始化并调用initialize*/ //parallel_for(BlockedRange(0, image.rows), // MOG2Invoker(image, fgmask, // (GMM*)bgmodel.data, // (float*)(bgmodel.data + sizeof(GMM)*nmixtures*image.rows*image.cols), // bgmodelUsedModes.data, nmixtures, (float)learningRate, // (float)varThreshold, // backgroundRatio, varThresholdGen, // fVarInit, fVarMin, fVarMax, float(-learningRate*fCT), fTau, // bShadowDetection, nShadowDetection)); } void OurBackgroundSubtractorMOG2::getBackgroundImage(OutputArray backgroundImage,OutputArray backgroundImageslow) const { } }
这是opencv中混合高斯模型代码的结构梳理 parallel_for的部分没有看懂 整个的结构还是很清晰的 更新部分的代码写在了结构体MOG2Invoker的重载操作符()中,然后在OurBackgroundSubtractorMOG2的重载操作符()中调用MOG2Inovker。为什么这样写不清楚,会效率更高吗?