Skip to content

Commit 97c0421

Browse files
committed
bgsegm: gmg: Relax source type and add test
1 parent b236c71 commit 97c0421

File tree

3 files changed

+53
-18
lines changed

3 files changed

+53
-18
lines changed

modules/bgsegm/include/opencv2/bgsegm.hpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,19 @@ CV_EXPORTS_W Ptr<BackgroundSubtractorMOG>
9999
class CV_EXPORTS_W BackgroundSubtractorGMG : public BackgroundSubtractor
100100
{
101101
public:
102+
// BackgroundSubtractor interface
103+
/** @brief Computes a foreground mask.
104+
105+
@param image Next video frame of type CV_8UC(n),CV_8SC(n),CV_16UC(n),CV_16SC(n),CV_32SC(n),CV_32FC(n),CV_64FC(n), where n is 1,2,3,4.
106+
@param fgmask The output foreground mask as an 8-bit binary image.
107+
@param learningRate The value between 0 and 1 that indicates how fast the background model is
108+
learnt. Negative parameter value makes the algorithm to use some automatically chosen learning
109+
rate. 0 means that the background model is not updated at all, 1 means that the background model
110+
is completely reinitialized from the last frame.
111+
*/
112+
CV_WRAP virtual void apply(InputArray image, OutputArray fgmask, double learningRate=-1) CV_OVERRIDE = 0;
113+
CV_WRAP virtual void getBackgroundImage(OutputArray backgroundImage) const CV_OVERRIDE = 0;
114+
102115
/** @brief Returns total number of distinct colors to maintain in histogram.
103116
*/
104117
CV_WRAP virtual int getMaxFeatures() const = 0;

modules/bgsegm/src/bgfg_gmg.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -426,8 +426,13 @@ void BackgroundSubtractorGMGImpl::apply(InputArray _frame, OutputArray _fgmask,
426426
{
427427
Mat frame = _frame.getMat();
428428

429-
CV_Assert(frame.depth() == CV_8U || frame.depth() == CV_16U || frame.depth() == CV_32F);
430-
CV_Assert(frame.channels() == 1 || frame.channels() == 3 || frame.channels() == 4);
429+
const int depth = frame.depth();
430+
CV_CheckDepth(depth, (depth == CV_8U) || (depth == CV_8S) ||
431+
(depth == CV_16U) || (depth == CV_16S) ||
432+
(depth == CV_32S) ||
433+
(depth == CV_32F) || (depth == CV_64F), "Unsupported depth");
434+
CV_CheckGE(frame.channels(), 1, "Unsupported channels");
435+
CV_CheckLE(frame.channels(), 4, "Unsupported channels");
431436

432437
if (newLearningRate != -1.0)
433438
{
@@ -441,8 +446,12 @@ void BackgroundSubtractorGMGImpl::apply(InputArray _frame, OutputArray _fgmask,
441446
double maxval = maxVal_;
442447
if( minVal_ == 0 && maxVal_ == 0 )
443448
{
444-
minval = 0;
445-
maxval = frame.depth() == CV_8U ? 255.0 : frame.depth() == CV_16U ? std::numeric_limits<ushort>::max() : 1.0;
449+
if( depth == CV_8U ) { minval = std::numeric_limits<uint8_t>::min(); maxval = std::numeric_limits<uint8_t>::max(); }
450+
else if( depth == CV_8S ) { minval = std::numeric_limits<int8_t>::min(); maxval = std::numeric_limits<int8_t>::max(); }
451+
else if( depth == CV_16U ) { minval = std::numeric_limits<uint16_t>::min();maxval = std::numeric_limits<uint16_t>::max();}
452+
else if( depth == CV_16S ) { minval = std::numeric_limits<int16_t>::min(); maxval = std::numeric_limits<int16_t>::max(); }
453+
else if( depth == CV_32S ) { minval = std::numeric_limits<int32_t>::min(); maxval = std::numeric_limits<int32_t>::max(); }
454+
else /* CV_32F or CV_64F */ { minval = 0.0; maxval = 1.0; }
446455
}
447456
initialize(frame.size(), minval, maxval);
448457
}

modules/bgsegm/test/test_backgroundsubtractor_gbh.cpp

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ class CV_BackgroundSubtractorTest : public cvtest::BaseTest
1111
{
1212
public:
1313
CV_BackgroundSubtractorTest();
14+
void setMatType(int _mtype){ mtype = _mtype; }
1415
protected:
16+
int mtype;
1517
void run(int);
1618
};
1719

@@ -29,11 +31,9 @@ void CV_BackgroundSubtractorTest::run(int)
2931
{
3032
int code = cvtest::TS::OK;
3133
RNG& rng = ts->get_rng();
32-
int type = ((unsigned int)rng)%7; //!< pick a random type, 0 - 6, defined in types_c.h
33-
int channels = 1 + ((unsigned int)rng)%4; //!< random number of channels from 1 to 4.
34-
int channelsAndType = CV_MAKETYPE(type,channels);
35-
int width = 2 + ((unsigned int)rng)%98; //!< Mat will be 2 to 100 in width and height
36-
int height = 2 + ((unsigned int)rng)%98;
34+
int depth = CV_MAT_DEPTH(mtype);
35+
int width = 64;
36+
int height = 64;
3737

3838
Ptr<BackgroundSubtractorGMG> fgbg = createBackgroundSubtractorGMG();
3939
Mat fgmask;
@@ -57,39 +57,39 @@ void CV_BackgroundSubtractorTest::run(int)
5757
* Max value for simulated images picked randomly in upper half of type range
5858
* Min value for simulated images picked randomly in lower half of type range
5959
*/
60-
if (type == CV_8U)
60+
if (depth == CV_8U)
6161
{
6262
uchar half = UCHAR_MAX/2;
6363
maxd = (unsigned char)rng.uniform(half+32, UCHAR_MAX);
6464
mind = (unsigned char)rng.uniform(0, half-32);
6565
}
66-
else if (type == CV_8S)
66+
else if (depth == CV_8S)
6767
{
6868
maxd = (char)rng.uniform(32, CHAR_MAX);
6969
mind = (char)rng.uniform(CHAR_MIN, -32);
7070
}
71-
else if (type == CV_16U)
71+
else if (depth == CV_16U)
7272
{
7373
ushort half = USHRT_MAX/2;
7474
maxd = (unsigned int)rng.uniform(half+32, USHRT_MAX);
7575
mind = (unsigned int)rng.uniform(0, half-32);
7676
}
77-
else if (type == CV_16S)
77+
else if (depth == CV_16S)
7878
{
7979
maxd = rng.uniform(32, SHRT_MAX);
8080
mind = rng.uniform(SHRT_MIN, -32);
8181
}
82-
else if (type == CV_32S)
82+
else if (depth == CV_32S)
8383
{
8484
maxd = rng.uniform(32, INT_MAX);
8585
mind = rng.uniform(INT_MIN, -32);
8686
}
87-
else if (type == CV_32F)
87+
else if (depth == CV_32F)
8888
{
8989
maxd = rng.uniform(32.0f, FLT_MAX);
9090
mind = rng.uniform(-FLT_MAX, -32.0f);
9191
}
92-
else if (type == CV_64F)
92+
else if (depth == CV_64F)
9393
{
9494
maxd = rng.uniform(32.0, DBL_MAX);
9595
mind = rng.uniform(-DBL_MAX, -32.0);
@@ -98,7 +98,7 @@ void CV_BackgroundSubtractorTest::run(int)
9898
fgbg->setMinVal(mind);
9999
fgbg->setMaxVal(maxd);
100100

101-
Mat simImage = Mat::zeros(height, width, channelsAndType);
101+
Mat simImage = Mat::zeros(height, width, mtype);
102102
int numLearningFrames = 120;
103103
for (int i = 0; i < numLearningFrames; ++i)
104104
{
@@ -132,6 +132,19 @@ void CV_BackgroundSubtractorTest::run(int)
132132

133133
}
134134

135-
TEST(VIDEO_BGSUBGMG, accuracy) { CV_BackgroundSubtractorTest test; test.safe_run(); }
135+
typedef testing::TestWithParam<std::tuple<perf::MatDepth,int>> bgsubgmg_allTypes;
136+
TEST_P(bgsubgmg_allTypes, accuracy)
137+
{
138+
const int mtype = CV_MAKETYPE(get<0>(GetParam()), get<1>(GetParam()));
139+
CV_BackgroundSubtractorTest test;
140+
test.setMatType(mtype);
141+
test.safe_run();
142+
}
143+
144+
INSTANTIATE_TEST_CASE_P(/**/,
145+
bgsubgmg_allTypes,
146+
testing::Combine(
147+
testing::Values(CV_8U, CV_8S, CV_16U, CV_16S, CV_32S, CV_32F, CV_64F),
148+
testing::Values(1,2,3,4)));
136149

137150
}} // namespace

0 commit comments

Comments
 (0)