/* 頭文件: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。為什么這樣寫不清楚,會效率更高嗎?