refactored MOG2 algorithm
authorVladislav Vinogradov <vlad.vinogradov@itseez.com>
Mon, 6 May 2013 13:41:13 +0000 (17:41 +0400)
committerVladislav Vinogradov <vlad.vinogradov@itseez.com>
Thu, 18 Jul 2013 11:39:42 +0000 (15:39 +0400)
modules/gpubgsegm/include/opencv2/gpubgsegm.hpp
modules/gpubgsegm/perf/perf_bgsegm.cpp
modules/gpubgsegm/src/mog2.cpp
modules/gpubgsegm/test/test_bgsegm.cpp
samples/gpu/bgfg_segm.cpp
samples/gpu/performance/tests.cpp

index b60d207..2b64f6e 100644 (file)
@@ -73,6 +73,27 @@ CV_EXPORTS Ptr<gpu::BackgroundSubtractorMOG>
     createBackgroundSubtractorMOG(int history = 200, int nmixtures = 5,
                                   double backgroundRatio = 0.7, double noiseSigma = 0);
 
+////////////////////////////////////////////////////
+// MOG2
+
+class CV_EXPORTS BackgroundSubtractorMOG2 : public cv::BackgroundSubtractorMOG2
+{
+public:
+    using cv::BackgroundSubtractorMOG2::apply;
+    using cv::BackgroundSubtractorMOG2::getBackgroundImage;
+
+    virtual void apply(InputArray image, OutputArray fgmask, double learningRate, Stream& stream) = 0;
+
+    virtual void getBackgroundImage(OutputArray backgroundImage, Stream& stream) const = 0;
+};
+
+CV_EXPORTS Ptr<gpu::BackgroundSubtractorMOG2>
+    createBackgroundSubtractorMOG2(int history = 500, double varThreshold = 16,
+                                   bool detectShadows = true);
+
+
+
+
 
 
 
@@ -140,99 +161,6 @@ private:
     std::auto_ptr<Impl> impl_;
 };
 
-/*!
- The class implements the following algorithm:
- "Improved adaptive Gausian mixture model for background subtraction"
- Z.Zivkovic
- International Conference Pattern Recognition, UK, August, 2004.
- http://www.zoranz.net/Publications/zivkovic2004ICPR.pdf
-*/
-class CV_EXPORTS MOG2_GPU
-{
-public:
-    //! the default constructor
-    MOG2_GPU(int nmixtures = -1);
-
-    //! re-initiaization method
-    void initialize(Size frameSize, int frameType);
-
-    //! the update operator
-    void operator()(const GpuMat& frame, GpuMat& fgmask, float learningRate = -1.0f, Stream& stream = Stream::Null());
-
-    //! computes a background image which are the mean of all background gaussians
-    void getBackgroundImage(GpuMat& backgroundImage, Stream& stream = Stream::Null()) const;
-
-    //! releases all inner buffers
-    void release();
-
-    // parameters
-    // you should call initialize after parameters changes
-
-    int history;
-
-    //! here it is the maximum allowed number of mixture components.
-    //! Actual number is determined dynamically per pixel
-    float varThreshold;
-    // threshold on the squared Mahalanobis distance to decide if it is well described
-    // by the background model or not. Related to Cthr from the paper.
-    // This does not influence the update of the background. A typical value could be 4 sigma
-    // and that is varThreshold=4*4=16; Corresponds to Tb in the paper.
-
-    /////////////////////////
-    // less important parameters - things you might change but be carefull
-    ////////////////////////
-
-    float backgroundRatio;
-    // corresponds to fTB=1-cf from the paper
-    // TB - threshold when the component becomes significant enough to be included into
-    // the background model. It is the TB=1-cf from the paper. So I use cf=0.1 => TB=0.
-    // For alpha=0.001 it means that the mode should exist for approximately 105 frames before
-    // it is considered foreground
-    // float noiseSigma;
-    float varThresholdGen;
-
-    //correspondts to Tg - threshold on the squared Mahalan. dist. to decide
-    //when a sample is close to the existing components. If it is not close
-    //to any a new component will be generated. I use 3 sigma => Tg=3*3=9.
-    //Smaller Tg leads to more generated components and higher Tg might make
-    //lead to small number of components but they can grow too large
-    float fVarInit;
-    float fVarMin;
-    float fVarMax;
-
-    //initial variance  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
-    // min and max can be used to further control the variance
-    float fCT; //CT - complexity reduction prior
-    //this is related to the number of samples needed to accept that a component
-    //actually exists. We use CT=0.05 of all the samples. By setting CT=0 you get
-    //the standard Stauffer&Grimson algorithm (maybe not exact but very similar)
-
-    //shadow detection parameters
-    bool bShadowDetection; //default 1 - do shadow detection
-    unsigned char nShadowDetection; //do shadow detection - insert this value as the detection result - 127 default value
-    float fTau;
-    // Tau - shadow threshold. The shadow is detected if the pixel is darker
-    //version of the background. Tau is a threshold on how much darker the shadow can be.
-    //Tau= 0.5 means that if pixel is more than 2 times darker then it is not shadow
-    //See: Prati,Mikic,Trivedi,Cucchiarra,"Detecting Moving Shadows...",IEEE PAMI,2003.
-
-private:
-    int nmixtures_;
-
-    Size frameSize_;
-    int frameType_;
-    int nframes_;
-
-    GpuMat weight_;
-    GpuMat variance_;
-    GpuMat mean_;
-
-    GpuMat bgmodelUsedModes_; //keep track of number of modes per pixel
-};
-
 /**
  * Background Subtractor module. Takes a series of images and returns a sequence of mask (8UC1)
  * images of the same size, where 255 indicates Foreground and 0 represents Background.
index a054288..8ec9c6f 100644 (file)
@@ -274,13 +274,13 @@ PERF_TEST_P(Video_Cn, MOG2,
 
     if (PERF_RUN_GPU())
     {
-        cv::gpu::MOG2_GPU d_mog2;
-        d_mog2.bShadowDetection = false;
+        cv::Ptr<cv::BackgroundSubtractorMOG2> d_mog2 = cv::gpu::createBackgroundSubtractorMOG2();
+        d_mog2->setDetectShadows(false);
 
         cv::gpu::GpuMat d_frame(frame);
         cv::gpu::GpuMat foreground;
 
-        d_mog2(d_frame, foreground);
+        d_mog2->apply(d_frame, foreground);
 
         for (int i = 0; i < 10; ++i)
         {
@@ -300,7 +300,7 @@ PERF_TEST_P(Video_Cn, MOG2,
             d_frame.upload(frame);
 
             startTimer(); next();
-            d_mog2(d_frame, foreground);
+            d_mog2->apply(d_frame, foreground);
             stopTimer();
         }
 
@@ -308,8 +308,8 @@ PERF_TEST_P(Video_Cn, MOG2,
     }
     else
     {
-        cv::Ptr<cv::BackgroundSubtractor> mog2 = cv::createBackgroundSubtractorMOG2();
-        mog2->set("detectShadows", false);
+        cv::Ptr<cv::BackgroundSubtractorMOG2> mog2 = cv::createBackgroundSubtractorMOG2();
+        mog2->setDetectShadows(false);
 
         cv::Mat foreground;
 
@@ -360,8 +360,9 @@ PERF_TEST_P(Video_Cn, MOG2GetBackgroundImage,
 
     if (PERF_RUN_GPU())
     {
+        cv::Ptr<cv::BackgroundSubtractor> d_mog2 = cv::gpu::createBackgroundSubtractorMOG2();
+
         cv::gpu::GpuMat d_frame;
-        cv::gpu::MOG2_GPU d_mog2;
         cv::gpu::GpuMat d_foreground;
 
         for (int i = 0; i < 10; ++i)
@@ -381,12 +382,12 @@ PERF_TEST_P(Video_Cn, MOG2GetBackgroundImage,
 
             d_frame.upload(frame);
 
-            d_mog2(d_frame, d_foreground);
+            d_mog2->apply(d_frame, d_foreground);
         }
 
         cv::gpu::GpuMat background;
 
-        TEST_CYCLE() d_mog2.getBackgroundImage(background);
+        TEST_CYCLE() d_mog2->getBackgroundImage(background);
 
         GPU_SANITY_CHECK(background, 1);
     }
index 7258294..5ab731f 100644 (file)
 
 #include "precomp.hpp"
 
+using namespace cv;
+using namespace cv::gpu;
+
 #if !defined HAVE_CUDA || defined(CUDA_DISABLER)
 
-cv::gpu::MOG2_GPU::MOG2_GPU(int) { throw_no_cuda(); }
-void cv::gpu::MOG2_GPU::initialize(cv::Size, int) { throw_no_cuda(); }
-void cv::gpu::MOG2_GPU::operator()(const GpuMat&, GpuMat&, float, Stream&) { throw_no_cuda(); }
-void cv::gpu::MOG2_GPU::getBackgroundImage(GpuMat&, Stream&) const { throw_no_cuda(); }
-void cv::gpu::MOG2_GPU::release() {}
+Ptr<gpu::BackgroundSubtractorMOG2> cv::gpu::createBackgroundSubtractorMOG2(int, double, bool) { throw_no_cuda(); return Ptr<gpu::BackgroundSubtractorMOG2>(); }
 
 #else
 
@@ -62,7 +61,7 @@ namespace cv { namespace gpu { namespace cudev
     }
 }}}
 
-namespace mog2
+namespace
 {
     // default parameters of gaussian background detection algorithm
     const int defaultHistory = 500; // Learning rate; alpha = 1/defaultHistory2
@@ -75,99 +74,180 @@ namespace mog2
     const float defaultVarMin = 4.0f;
 
     // additional parameters
-    const float defaultfCT = 0.05f; // complexity reduction prior constant 0 - no reduction of number of components
-    const unsigned char defaultnShadowDetection = 127; // value to use in the segmentation mask for shadows, set 0 not to do shadow detection
-    const float defaultfTau = 0.5f; // Tau - shadow threshold, see the paper for explanation
-}
+    const float defaultCT = 0.05f; // complexity reduction prior constant 0 - no reduction of number of components
+    const unsigned char defaultShadowValue = 127; // value to use in the segmentation mask for shadows, set 0 not to do shadow detection
+    const float defaultShadowThreshold = 0.5f; // Tau - shadow threshold, see the paper for explanation
 
-cv::gpu::MOG2_GPU::MOG2_GPU(int nmixtures) :
-    frameSize_(0, 0), frameType_(0), nframes_(0)
-{
-    nmixtures_ = nmixtures > 0 ? nmixtures : mog2::defaultNMixtures;
+    class MOG2Impl : public gpu::BackgroundSubtractorMOG2
+    {
+    public:
+        MOG2Impl(int history, double varThreshold, bool detectShadows);
 
-    history = mog2::defaultHistory;
-    varThreshold = mog2::defaultVarThreshold;
-    bShadowDetection = true;
+        void apply(InputArray image, OutputArray fgmask, double learningRate=-1);
+        void apply(InputArray image, OutputArray fgmask, double learningRate, Stream& stream);
 
-    backgroundRatio = mog2::defaultBackgroundRatio;
-    fVarInit = mog2::defaultVarInit;
-    fVarMax  = mog2::defaultVarMax;
-    fVarMin = mog2::defaultVarMin;
+        void getBackgroundImage(OutputArray backgroundImage) const;
+        void getBackgroundImage(OutputArray backgroundImage, Stream& stream) const;
 
-    varThresholdGen = mog2::defaultVarThresholdGen;
-    fCT = mog2::defaultfCT;
-    nShadowDetection =  mog2::defaultnShadowDetection;
-    fTau = mog2::defaultfTau;
-}
+        int getHistory() const { return history_; }
+        void setHistory(int history) { history_ = history; }
 
-void cv::gpu::MOG2_GPU::initialize(cv::Size frameSize, int frameType)
-{
-    using namespace cv::gpu::cudev::mog2;
+        int getNMixtures() const { return nmixtures_; }
+        void setNMixtures(int nmixtures) { nmixtures_ = nmixtures; }
 
-    CV_Assert(frameType == CV_8UC1 || frameType == CV_8UC3 || frameType == CV_8UC4);
+        double getBackgroundRatio() const { return backgroundRatio_; }
+        void setBackgroundRatio(double ratio) { backgroundRatio_ = (float) ratio; }
 
-    frameSize_ = frameSize;
-    frameType_ = frameType;
-    nframes_ = 0;
+        double getVarThreshold() const { return varThreshold_; }
+        void setVarThreshold(double varThreshold) { varThreshold_ = (float) varThreshold; }
 
-    int ch = CV_MAT_CN(frameType);
-    int work_ch = ch;
+        double getVarThresholdGen() const { return varThresholdGen_; }
+        void setVarThresholdGen(double varThresholdGen) { varThresholdGen_ = (float) varThresholdGen; }
 
-    // for each gaussian mixture of each pixel bg model we store ...
-    // the mixture weight (w),
-    // the mean (nchannels values) and
-    // the covariance
-    weight_.create(frameSize.height * nmixtures_, frameSize_.width, CV_32FC1);
-    variance_.create(frameSize.height * nmixtures_, frameSize_.width, CV_32FC1);
-    mean_.create(frameSize.height * nmixtures_, frameSize_.width, CV_32FC(work_ch));
+        double getVarInit() const { return varInit_; }
+        void setVarInit(double varInit) { varInit_ = (float) varInit; }
 
-    //make the array for keeping track of the used modes per pixel - all zeros at start
-    bgmodelUsedModes_.create(frameSize_, CV_8UC1);
-    bgmodelUsedModes_.setTo(cv::Scalar::all(0));
+        double getVarMin() const { return varMin_; }
+        void setVarMin(double varMin) { varMin_ = (float) varMin; }
 
-    loadConstants(nmixtures_, varThreshold, backgroundRatio, varThresholdGen, fVarInit, fVarMin, fVarMax, fTau, nShadowDetection);
-}
+        double getVarMax() const { return varMax_; }
+        void setVarMax(double varMax) { varMax_ = (float) varMax; }
 
-void cv::gpu::MOG2_GPU::operator()(const GpuMat& frame, GpuMat& fgmask, float learningRate, Stream& stream)
-{
-    using namespace cv::gpu::cudev::mog2;
+        double getComplexityReductionThreshold() const { return ct_; }
+        void setComplexityReductionThreshold(double ct) { ct_ = (float) ct; }
 
-    int ch = frame.channels();
-    int work_ch = ch;
+        bool getDetectShadows() const { return detectShadows_; }
+        void setDetectShadows(bool detectShadows) { detectShadows_ = detectShadows; }
 
-    if (nframes_ == 0 || learningRate >= 1.0f || frame.size() != frameSize_ || work_ch != mean_.channels())
-        initialize(frame.size(), frame.type());
+        int getShadowValue() const { return shadowValue_; }
+        void setShadowValue(int value) { shadowValue_ = (uchar) value; }
 
-    fgmask.create(frameSize_, CV_8UC1);
-    fgmask.setTo(cv::Scalar::all(0));
+        double getShadowThreshold() const { return shadowThreshold_; }
+        void setShadowThreshold(double threshold) { shadowThreshold_ = (float) threshold; }
 
-    ++nframes_;
-    learningRate = learningRate >= 0.0f && nframes_ > 1 ? learningRate : 1.0f / std::min(2 * nframes_, history);
-    CV_Assert(learningRate >= 0.0f);
+    private:
+        void initialize(Size frameSize, int frameType);
 
-    mog2_gpu(frame, frame.channels(), fgmask, bgmodelUsedModes_, weight_, variance_, mean_, learningRate, -learningRate * fCT, bShadowDetection, StreamAccessor::getStream(stream));
-}
+        int history_;
+        int nmixtures_;
+        float backgroundRatio_;
+        float varThreshold_;
+        float varThresholdGen_;
+        float varInit_;
+        float varMin_;
+        float varMax_;
+        float ct_;
+        bool detectShadows_;
+        uchar shadowValue_;
+        float shadowThreshold_;
 
-void cv::gpu::MOG2_GPU::getBackgroundImage(GpuMat& backgroundImage, Stream& stream) const
-{
-    using namespace cv::gpu::cudev::mog2;
+        Size frameSize_;
+        int frameType_;
+        int nframes_;
 
-    backgroundImage.create(frameSize_, frameType_);
+        GpuMat weight_;
+        GpuMat variance_;
+        GpuMat mean_;
 
-    getBackgroundImage2_gpu(backgroundImage.channels(), bgmodelUsedModes_, weight_, mean_, backgroundImage, StreamAccessor::getStream(stream));
-}
+        //keep track of number of modes per pixel
+        GpuMat bgmodelUsedModes_;
+    };
 
-void cv::gpu::MOG2_GPU::release()
-{
-    frameSize_ = Size(0, 0);
-    frameType_ = 0;
-    nframes_ = 0;
+    MOG2Impl::MOG2Impl(int history, double varThreshold, bool detectShadows) :
+        frameSize_(0, 0), frameType_(0), nframes_(0)
+    {
+        history_ = history > 0 ? history : defaultHistory;
+        varThreshold_ = varThreshold > 0 ? (float) varThreshold : defaultVarThreshold;
+        detectShadows_ = detectShadows;
+
+        nmixtures_ = defaultNMixtures;
+        backgroundRatio_ = defaultBackgroundRatio;
+        varInit_ = defaultVarInit;
+        varMax_ = defaultVarMax;
+        varMin_ = defaultVarMin;
+        varThresholdGen_ = defaultVarThresholdGen;
+        ct_ = defaultCT;
+        shadowValue_ =  defaultShadowValue;
+        shadowThreshold_ = defaultShadowThreshold;
+    }
+
+    void MOG2Impl::apply(InputArray image, OutputArray fgmask, double learningRate)
+    {
+        apply(image, fgmask, learningRate, Stream::Null());
+    }
+
+    void MOG2Impl::apply(InputArray _frame, OutputArray _fgmask, double learningRate, Stream& stream)
+    {
+        using namespace cv::gpu::cudev::mog2;
+
+        GpuMat frame = _frame.getGpuMat();
+
+        int ch = frame.channels();
+        int work_ch = ch;
+
+        if (nframes_ == 0 || learningRate >= 1.0 || frame.size() != frameSize_ || work_ch != mean_.channels())
+            initialize(frame.size(), frame.type());
+
+        _fgmask.create(frameSize_, CV_8UC1);
+        GpuMat fgmask = _fgmask.getGpuMat();
 
-    weight_.release();
-    variance_.release();
-    mean_.release();
+        fgmask.setTo(Scalar::all(0), stream);
 
-    bgmodelUsedModes_.release();
+        ++nframes_;
+        learningRate = learningRate >= 0 && nframes_ > 1 ? learningRate : 1.0 / std::min(2 * nframes_, history_);
+        CV_Assert( learningRate >= 0 );
+
+        mog2_gpu(frame, frame.channels(), fgmask, bgmodelUsedModes_, weight_, variance_, mean_,
+                 (float) learningRate, static_cast<float>(-learningRate * ct_), detectShadows_, StreamAccessor::getStream(stream));
+    }
+
+    void MOG2Impl::getBackgroundImage(OutputArray backgroundImage) const
+    {
+        getBackgroundImage(backgroundImage, Stream::Null());
+    }
+
+    void MOG2Impl::getBackgroundImage(OutputArray _backgroundImage, Stream& stream) const
+    {
+        using namespace cv::gpu::cudev::mog2;
+
+        _backgroundImage.create(frameSize_, frameType_);
+        GpuMat backgroundImage = _backgroundImage.getGpuMat();
+
+        getBackgroundImage2_gpu(backgroundImage.channels(), bgmodelUsedModes_, weight_, mean_, backgroundImage, StreamAccessor::getStream(stream));
+    }
+
+    void MOG2Impl::initialize(cv::Size frameSize, int frameType)
+    {
+        using namespace cv::gpu::cudev::mog2;
+
+        CV_Assert( frameType == CV_8UC1 || frameType == CV_8UC3 || frameType == CV_8UC4 );
+
+        frameSize_ = frameSize;
+        frameType_ = frameType;
+        nframes_ = 0;
+
+        int ch = CV_MAT_CN(frameType);
+        int work_ch = ch;
+
+        // for each gaussian mixture of each pixel bg model we store ...
+        // the mixture weight (w),
+        // the mean (nchannels values) and
+        // the covariance
+        weight_.create(frameSize.height * nmixtures_, frameSize_.width, CV_32FC1);
+        variance_.create(frameSize.height * nmixtures_, frameSize_.width, CV_32FC1);
+        mean_.create(frameSize.height * nmixtures_, frameSize_.width, CV_32FC(work_ch));
+
+        //make the array for keeping track of the used modes per pixel - all zeros at start
+        bgmodelUsedModes_.create(frameSize_, CV_8UC1);
+        bgmodelUsedModes_.setTo(Scalar::all(0));
+
+        loadConstants(nmixtures_, varThreshold_, backgroundRatio_, varThresholdGen_, varInit_, varMin_, varMax_, shadowThreshold_, shadowValue_);
+    }
+}
+
+Ptr<gpu::BackgroundSubtractorMOG2> cv::gpu::createBackgroundSubtractorMOG2(int history, double varThreshold, bool detectShadows)
+{
+    return new MOG2Impl(history, varThreshold, detectShadows);
 }
 
 #endif
index 588db8b..4ff505f 100644 (file)
@@ -267,8 +267,8 @@ GPU_TEST_P(MOG2, Update)
     cap >> frame;
     ASSERT_FALSE(frame.empty());
 
-    cv::gpu::MOG2_GPU mog2;
-    mog2.bShadowDetection = detectShadow;
+    cv::Ptr<cv::BackgroundSubtractorMOG2> mog2 = cv::gpu::createBackgroundSubtractorMOG2();
+    mog2->setDetectShadows(detectShadow);
     cv::gpu::GpuMat foreground = createMat(frame.size(), CV_8UC1, useRoi);
 
     cv::Ptr<cv::BackgroundSubtractorMOG2> mog2_gold = cv::createBackgroundSubtractorMOG2();
@@ -287,7 +287,7 @@ GPU_TEST_P(MOG2, Update)
             cv::swap(temp, frame);
         }
 
-        mog2(loadMat(frame, useRoi), foreground);
+        mog2->apply(loadMat(frame, useRoi), foreground);
 
         mog2_gold->apply(frame, foreground_gold);
 
@@ -312,8 +312,8 @@ GPU_TEST_P(MOG2, getBackgroundImage)
 
     cv::Mat frame;
 
-    cv::gpu::MOG2_GPU mog2;
-    mog2.bShadowDetection = detectShadow;
+    cv::Ptr<cv::BackgroundSubtractorMOG2> mog2 = cv::gpu::createBackgroundSubtractorMOG2();
+    mog2->setDetectShadows(detectShadow);
     cv::gpu::GpuMat foreground;
 
     cv::Ptr<cv::BackgroundSubtractorMOG2> mog2_gold = cv::createBackgroundSubtractorMOG2();
@@ -325,13 +325,13 @@ GPU_TEST_P(MOG2, getBackgroundImage)
         cap >> frame;
         ASSERT_FALSE(frame.empty());
 
-        mog2(loadMat(frame, useRoi), foreground);
+        mog2->apply(loadMat(frame, useRoi), foreground);
 
         mog2_gold->apply(frame, foreground_gold);
     }
 
     cv::gpu::GpuMat background = createMat(frame.size(), frame.type(), useRoi);
-    mog2.getBackgroundImage(background);
+    mog2->getBackgroundImage(background);
 
     cv::Mat background_gold;
     mog2_gold->getBackgroundImage(background_gold);
index 3fe26a9..01d8680 100644 (file)
@@ -76,8 +76,8 @@ int main(int argc, const char** argv)
     GpuMat d_frame(frame);
 
     FGDStatModel fgd_stat;
-    cv::Ptr<cv::BackgroundSubtractorMOG> mog = cv::gpu::createBackgroundSubtractorMOG();
-    MOG2_GPU mog2;
+    cv::Ptr<cv::BackgroundSubtractor> mog = cv::gpu::createBackgroundSubtractorMOG();
+    cv::Ptr<cv::BackgroundSubtractor> mog2 = cv::gpu::createBackgroundSubtractorMOG2();
     GMG_GPU gmg;
     gmg.numInitializationFrames = 40;
 
@@ -100,7 +100,7 @@ int main(int argc, const char** argv)
         break;
 
     case MOG2:
-        mog2(d_frame, d_fgmask);
+        mog2->apply(d_frame, d_fgmask);
         break;
 
     case GMG:
@@ -140,8 +140,8 @@ int main(int argc, const char** argv)
             break;
 
         case MOG2:
-            mog2(d_frame, d_fgmask);
-            mog2.getBackgroundImage(d_bgimg);
+            mog2->apply(d_frame, d_fgmask);
+            mog2->getBackgroundImage(d_bgimg);
             break;
 
         case GMG:
index 3681ff9..b0217c3 100644 (file)
@@ -1399,13 +1399,13 @@ TEST(MOG2)
 
     cap >> frame;
 
+    cv::Ptr<cv::BackgroundSubtractor> d_mog2 = cv::gpu::createBackgroundSubtractorMOG2();
     cv::gpu::GpuMat d_frame(frame);
-    cv::gpu::MOG2_GPU d_mog2;
     cv::gpu::GpuMat d_foreground;
     cv::gpu::GpuMat d_background;
 
-    d_mog2(d_frame, d_foreground);
-    d_mog2.getBackgroundImage(d_background);
+    d_mog2->apply(d_frame, d_foreground);
+    d_mog2->getBackgroundImage(d_background);
 
     while (!TestSystem::instance().stop())
     {
@@ -1414,8 +1414,8 @@ TEST(MOG2)
 
         TestSystem::instance().gpuOn();
 
-        d_mog2(d_frame, d_foreground);
-        d_mog2.getBackgroundImage(d_background);
+        d_mog2->apply(d_frame, d_foreground);
+        d_mog2->getBackgroundImage(d_background);
 
         TestSystem::instance().gpuOff();
     }