提交 b8f0d1a0 编写于 作者: V Vladislav Vinogradov

refactored MOG2 algorithm

上级 a2adab72
...@@ -73,6 +73,27 @@ CV_EXPORTS Ptr<gpu::BackgroundSubtractorMOG> ...@@ -73,6 +73,27 @@ CV_EXPORTS Ptr<gpu::BackgroundSubtractorMOG>
createBackgroundSubtractorMOG(int history = 200, int nmixtures = 5, createBackgroundSubtractorMOG(int history = 200, int nmixtures = 5,
double backgroundRatio = 0.7, double noiseSigma = 0); 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: ...@@ -140,99 +161,6 @@ private:
std::auto_ptr<Impl> impl_; 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) * 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. * images of the same size, where 255 indicates Foreground and 0 represents Background.
......
...@@ -274,13 +274,13 @@ PERF_TEST_P(Video_Cn, MOG2, ...@@ -274,13 +274,13 @@ PERF_TEST_P(Video_Cn, MOG2,
if (PERF_RUN_GPU()) if (PERF_RUN_GPU())
{ {
cv::gpu::MOG2_GPU d_mog2; cv::Ptr<cv::BackgroundSubtractorMOG2> d_mog2 = cv::gpu::createBackgroundSubtractorMOG2();
d_mog2.bShadowDetection = false; d_mog2->setDetectShadows(false);
cv::gpu::GpuMat d_frame(frame); cv::gpu::GpuMat d_frame(frame);
cv::gpu::GpuMat foreground; cv::gpu::GpuMat foreground;
d_mog2(d_frame, foreground); d_mog2->apply(d_frame, foreground);
for (int i = 0; i < 10; ++i) for (int i = 0; i < 10; ++i)
{ {
...@@ -300,7 +300,7 @@ PERF_TEST_P(Video_Cn, MOG2, ...@@ -300,7 +300,7 @@ PERF_TEST_P(Video_Cn, MOG2,
d_frame.upload(frame); d_frame.upload(frame);
startTimer(); next(); startTimer(); next();
d_mog2(d_frame, foreground); d_mog2->apply(d_frame, foreground);
stopTimer(); stopTimer();
} }
...@@ -308,8 +308,8 @@ PERF_TEST_P(Video_Cn, MOG2, ...@@ -308,8 +308,8 @@ PERF_TEST_P(Video_Cn, MOG2,
} }
else else
{ {
cv::Ptr<cv::BackgroundSubtractor> mog2 = cv::createBackgroundSubtractorMOG2(); cv::Ptr<cv::BackgroundSubtractorMOG2> mog2 = cv::createBackgroundSubtractorMOG2();
mog2->set("detectShadows", false); mog2->setDetectShadows(false);
cv::Mat foreground; cv::Mat foreground;
...@@ -360,8 +360,9 @@ PERF_TEST_P(Video_Cn, MOG2GetBackgroundImage, ...@@ -360,8 +360,9 @@ PERF_TEST_P(Video_Cn, MOG2GetBackgroundImage,
if (PERF_RUN_GPU()) if (PERF_RUN_GPU())
{ {
cv::Ptr<cv::BackgroundSubtractor> d_mog2 = cv::gpu::createBackgroundSubtractorMOG2();
cv::gpu::GpuMat d_frame; cv::gpu::GpuMat d_frame;
cv::gpu::MOG2_GPU d_mog2;
cv::gpu::GpuMat d_foreground; cv::gpu::GpuMat d_foreground;
for (int i = 0; i < 10; ++i) for (int i = 0; i < 10; ++i)
...@@ -381,12 +382,12 @@ PERF_TEST_P(Video_Cn, MOG2GetBackgroundImage, ...@@ -381,12 +382,12 @@ PERF_TEST_P(Video_Cn, MOG2GetBackgroundImage,
d_frame.upload(frame); d_frame.upload(frame);
d_mog2(d_frame, d_foreground); d_mog2->apply(d_frame, d_foreground);
} }
cv::gpu::GpuMat background; cv::gpu::GpuMat background;
TEST_CYCLE() d_mog2.getBackgroundImage(background); TEST_CYCLE() d_mog2->getBackgroundImage(background);
GPU_SANITY_CHECK(background, 1); GPU_SANITY_CHECK(background, 1);
} }
......
...@@ -42,13 +42,12 @@ ...@@ -42,13 +42,12 @@
#include "precomp.hpp" #include "precomp.hpp"
using namespace cv;
using namespace cv::gpu;
#if !defined HAVE_CUDA || defined(CUDA_DISABLER) #if !defined HAVE_CUDA || defined(CUDA_DISABLER)
cv::gpu::MOG2_GPU::MOG2_GPU(int) { throw_no_cuda(); } Ptr<gpu::BackgroundSubtractorMOG2> cv::gpu::createBackgroundSubtractorMOG2(int, double, bool) { throw_no_cuda(); return Ptr<gpu::BackgroundSubtractorMOG2>(); }
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() {}
#else #else
...@@ -62,7 +61,7 @@ namespace cv { namespace gpu { namespace cudev ...@@ -62,7 +61,7 @@ namespace cv { namespace gpu { namespace cudev
} }
}}} }}}
namespace mog2 namespace
{ {
// default parameters of gaussian background detection algorithm // default parameters of gaussian background detection algorithm
const int defaultHistory = 500; // Learning rate; alpha = 1/defaultHistory2 const int defaultHistory = 500; // Learning rate; alpha = 1/defaultHistory2
...@@ -75,99 +74,180 @@ namespace mog2 ...@@ -75,99 +74,180 @@ namespace mog2
const float defaultVarMin = 4.0f; const float defaultVarMin = 4.0f;
// additional parameters // additional parameters
const float defaultfCT = 0.05f; // complexity reduction prior constant 0 - no reduction of number of components const float defaultCT = 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 unsigned char defaultShadowValue = 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 defaultShadowThreshold = 0.5f; // Tau - shadow threshold, see the paper for explanation
}
cv::gpu::MOG2_GPU::MOG2_GPU(int nmixtures) : class MOG2Impl : public gpu::BackgroundSubtractorMOG2
frameSize_(0, 0), frameType_(0), nframes_(0) {
{ public:
nmixtures_ = nmixtures > 0 ? nmixtures : mog2::defaultNMixtures; MOG2Impl(int history, double varThreshold, bool detectShadows);
history = mog2::defaultHistory; void apply(InputArray image, OutputArray fgmask, double learningRate=-1);
varThreshold = mog2::defaultVarThreshold; void apply(InputArray image, OutputArray fgmask, double learningRate, Stream& stream);
bShadowDetection = true;
backgroundRatio = mog2::defaultBackgroundRatio; void getBackgroundImage(OutputArray backgroundImage) const;
fVarInit = mog2::defaultVarInit; void getBackgroundImage(OutputArray backgroundImage, Stream& stream) const;
fVarMax = mog2::defaultVarMax;
fVarMin = mog2::defaultVarMin;
varThresholdGen = mog2::defaultVarThresholdGen; int getHistory() const { return history_; }
fCT = mog2::defaultfCT; void setHistory(int history) { history_ = history; }
nShadowDetection = mog2::defaultnShadowDetection;
fTau = mog2::defaultfTau;
}
void cv::gpu::MOG2_GPU::initialize(cv::Size frameSize, int frameType) int getNMixtures() const { return nmixtures_; }
{ void setNMixtures(int nmixtures) { nmixtures_ = nmixtures; }
using namespace cv::gpu::cudev::mog2;
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; double getVarThreshold() const { return varThreshold_; }
frameType_ = frameType; void setVarThreshold(double varThreshold) { varThreshold_ = (float) varThreshold; }
nframes_ = 0;
int ch = CV_MAT_CN(frameType); double getVarThresholdGen() const { return varThresholdGen_; }
int work_ch = ch; void setVarThresholdGen(double varThresholdGen) { varThresholdGen_ = (float) varThresholdGen; }
// for each gaussian mixture of each pixel bg model we store ... double getVarInit() const { return varInit_; }
// the mixture weight (w), void setVarInit(double varInit) { varInit_ = (float) varInit; }
// 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 double getVarMin() const { return varMin_; }
bgmodelUsedModes_.create(frameSize_, CV_8UC1); void setVarMin(double varMin) { varMin_ = (float) varMin; }
bgmodelUsedModes_.setTo(cv::Scalar::all(0));
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) double getComplexityReductionThreshold() const { return ct_; }
{ void setComplexityReductionThreshold(double ct) { ct_ = (float) ct; }
using namespace cv::gpu::cudev::mog2;
int ch = frame.channels(); bool getDetectShadows() const { return detectShadows_; }
int work_ch = ch; void setDetectShadows(bool detectShadows) { detectShadows_ = detectShadows; }
if (nframes_ == 0 || learningRate >= 1.0f || frame.size() != frameSize_ || work_ch != mean_.channels()) int getShadowValue() const { return shadowValue_; }
initialize(frame.size(), frame.type()); void setShadowValue(int value) { shadowValue_ = (uchar) value; }
fgmask.create(frameSize_, CV_8UC1); double getShadowThreshold() const { return shadowThreshold_; }
fgmask.setTo(cv::Scalar::all(0)); void setShadowThreshold(double threshold) { shadowThreshold_ = (float) threshold; }
++nframes_; private:
learningRate = learningRate >= 0.0f && nframes_ > 1 ? learningRate : 1.0f / std::min(2 * nframes_, history); void initialize(Size frameSize, int frameType);
CV_Assert(learningRate >= 0.0f);
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 Size frameSize_;
{ int frameType_;
using namespace cv::gpu::cudev::mog2; 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() MOG2Impl::MOG2Impl(int history, double varThreshold, bool detectShadows) :
{ frameSize_(0, 0), frameType_(0), nframes_(0)
frameSize_ = Size(0, 0); {
frameType_ = 0; history_ = history > 0 ? history : defaultHistory;
nframes_ = 0; 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(); fgmask.setTo(Scalar::all(0), stream);
variance_.release();
mean_.release();
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 #endif
...@@ -267,8 +267,8 @@ GPU_TEST_P(MOG2, Update) ...@@ -267,8 +267,8 @@ GPU_TEST_P(MOG2, Update)
cap >> frame; cap >> frame;
ASSERT_FALSE(frame.empty()); ASSERT_FALSE(frame.empty());
cv::gpu::MOG2_GPU mog2; cv::Ptr<cv::BackgroundSubtractorMOG2> mog2 = cv::gpu::createBackgroundSubtractorMOG2();
mog2.bShadowDetection = detectShadow; mog2->setDetectShadows(detectShadow);
cv::gpu::GpuMat foreground = createMat(frame.size(), CV_8UC1, useRoi); cv::gpu::GpuMat foreground = createMat(frame.size(), CV_8UC1, useRoi);
cv::Ptr<cv::BackgroundSubtractorMOG2> mog2_gold = cv::createBackgroundSubtractorMOG2(); cv::Ptr<cv::BackgroundSubtractorMOG2> mog2_gold = cv::createBackgroundSubtractorMOG2();
...@@ -287,7 +287,7 @@ GPU_TEST_P(MOG2, Update) ...@@ -287,7 +287,7 @@ GPU_TEST_P(MOG2, Update)
cv::swap(temp, frame); cv::swap(temp, frame);
} }
mog2(loadMat(frame, useRoi), foreground); mog2->apply(loadMat(frame, useRoi), foreground);
mog2_gold->apply(frame, foreground_gold); mog2_gold->apply(frame, foreground_gold);
...@@ -312,8 +312,8 @@ GPU_TEST_P(MOG2, getBackgroundImage) ...@@ -312,8 +312,8 @@ GPU_TEST_P(MOG2, getBackgroundImage)
cv::Mat frame; cv::Mat frame;
cv::gpu::MOG2_GPU mog2; cv::Ptr<cv::BackgroundSubtractorMOG2> mog2 = cv::gpu::createBackgroundSubtractorMOG2();
mog2.bShadowDetection = detectShadow; mog2->setDetectShadows(detectShadow);
cv::gpu::GpuMat foreground; cv::gpu::GpuMat foreground;
cv::Ptr<cv::BackgroundSubtractorMOG2> mog2_gold = cv::createBackgroundSubtractorMOG2(); cv::Ptr<cv::BackgroundSubtractorMOG2> mog2_gold = cv::createBackgroundSubtractorMOG2();
...@@ -325,13 +325,13 @@ GPU_TEST_P(MOG2, getBackgroundImage) ...@@ -325,13 +325,13 @@ GPU_TEST_P(MOG2, getBackgroundImage)
cap >> frame; cap >> frame;
ASSERT_FALSE(frame.empty()); ASSERT_FALSE(frame.empty());
mog2(loadMat(frame, useRoi), foreground); mog2->apply(loadMat(frame, useRoi), foreground);
mog2_gold->apply(frame, foreground_gold); mog2_gold->apply(frame, foreground_gold);
} }
cv::gpu::GpuMat background = createMat(frame.size(), frame.type(), useRoi); cv::gpu::GpuMat background = createMat(frame.size(), frame.type(), useRoi);
mog2.getBackgroundImage(background); mog2->getBackgroundImage(background);
cv::Mat background_gold; cv::Mat background_gold;
mog2_gold->getBackgroundImage(background_gold); mog2_gold->getBackgroundImage(background_gold);
......
...@@ -76,8 +76,8 @@ int main(int argc, const char** argv) ...@@ -76,8 +76,8 @@ int main(int argc, const char** argv)
GpuMat d_frame(frame); GpuMat d_frame(frame);
FGDStatModel fgd_stat; FGDStatModel fgd_stat;
cv::Ptr<cv::BackgroundSubtractorMOG> mog = cv::gpu::createBackgroundSubtractorMOG(); cv::Ptr<cv::BackgroundSubtractor> mog = cv::gpu::createBackgroundSubtractorMOG();
MOG2_GPU mog2; cv::Ptr<cv::BackgroundSubtractor> mog2 = cv::gpu::createBackgroundSubtractorMOG2();
GMG_GPU gmg; GMG_GPU gmg;
gmg.numInitializationFrames = 40; gmg.numInitializationFrames = 40;
...@@ -100,7 +100,7 @@ int main(int argc, const char** argv) ...@@ -100,7 +100,7 @@ int main(int argc, const char** argv)
break; break;
case MOG2: case MOG2:
mog2(d_frame, d_fgmask); mog2->apply(d_frame, d_fgmask);
break; break;
case GMG: case GMG:
...@@ -140,8 +140,8 @@ int main(int argc, const char** argv) ...@@ -140,8 +140,8 @@ int main(int argc, const char** argv)
break; break;
case MOG2: case MOG2:
mog2(d_frame, d_fgmask); mog2->apply(d_frame, d_fgmask);
mog2.getBackgroundImage(d_bgimg); mog2->getBackgroundImage(d_bgimg);
break; break;
case GMG: case GMG:
......
...@@ -1399,13 +1399,13 @@ TEST(MOG2) ...@@ -1399,13 +1399,13 @@ TEST(MOG2)
cap >> frame; cap >> frame;
cv::Ptr<cv::BackgroundSubtractor> d_mog2 = cv::gpu::createBackgroundSubtractorMOG2();
cv::gpu::GpuMat d_frame(frame); cv::gpu::GpuMat d_frame(frame);
cv::gpu::MOG2_GPU d_mog2;
cv::gpu::GpuMat d_foreground; cv::gpu::GpuMat d_foreground;
cv::gpu::GpuMat d_background; cv::gpu::GpuMat d_background;
d_mog2(d_frame, d_foreground); d_mog2->apply(d_frame, d_foreground);
d_mog2.getBackgroundImage(d_background); d_mog2->getBackgroundImage(d_background);
while (!TestSystem::instance().stop()) while (!TestSystem::instance().stop())
{ {
...@@ -1414,8 +1414,8 @@ TEST(MOG2) ...@@ -1414,8 +1414,8 @@ TEST(MOG2)
TestSystem::instance().gpuOn(); TestSystem::instance().gpuOn();
d_mog2(d_frame, d_foreground); d_mog2->apply(d_frame, d_foreground);
d_mog2.getBackgroundImage(d_background); d_mog2->getBackgroundImage(d_background);
TestSystem::instance().gpuOff(); TestSystem::instance().gpuOff();
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册