77
88namespace opencv_test { namespace {
99
10- class CV_BackgroundSubtractorTest : public cvtest ::BaseTest
11- {
12- public:
13- CV_BackgroundSubtractorTest ();
14- protected:
15- void run (int );
16- };
17-
18- CV_BackgroundSubtractorTest::CV_BackgroundSubtractorTest ()
19- {
20- }
21-
2210/* *
2311 * This test checks the following:
2412 * (i) BackgroundSubtractorGMG can operate with matrices of various types and sizes
2513 * (ii) Training mode returns empty fgmask
2614 * (iii) End of training mode, and anomalous frame yields every pixel detected as FG
2715 */
28- void CV_BackgroundSubtractorTest::run (int )
16+ typedef testing::TestWithParam<std::tuple<perf::MatDepth,int >> bgsubgmg_allTypes;
17+ TEST_P (bgsubgmg_allTypes, accuracy)
2918{
30- int code = cvtest::TS::OK;
31- RNG& rng = ts->get_rng ();
32- int type = ((unsigned int )rng) % 3 ;
33- type = (type == 0 ) ? CV_8U : (type == 1 ) ? CV_16U : CV_32F; // 8U, 16U, 32F
34- int channels = ((unsigned int )rng)%3 ;
35- channels = (channels == 2 ) ? 4 : channels; // 1, 3, 4
36- int channelsAndType = CV_MAKETYPE (type,channels);
37- int width = 2 + ((unsigned int )rng)%98 ; // !< Mat will be 2 to 100 in width and height
38- int height = 2 + ((unsigned int )rng)%98 ;
19+ const int depth = get<0 >(GetParam ());
20+ const int ncn = get<1 >(GetParam ());
21+ const int mtype = CV_MAKETYPE (depth, ncn);
22+ const int width = 64 ;
23+ const int height = 64 ;
24+ RNG& rng = TS::ptr ()->get_rng ();
3925
4026 Ptr<BackgroundSubtractorGMG> fgbg = createBackgroundSubtractorGMG ();
41- Mat fgmask;
42-
43- if (!fgbg)
44- CV_Error (Error::StsError," Failed to create Algorithm\n " );
27+ ASSERT_TRUE (fgbg != nullptr ) << " Failed to call createBackgroundSubtractorGMG()" ;
4528
4629 /* *
4730 * Set a few parameters
@@ -59,49 +42,51 @@ void CV_BackgroundSubtractorTest::run(int)
5942 * Max value for simulated images picked randomly in upper half of type range
6043 * Min value for simulated images picked randomly in lower half of type range
6144 */
62- if (type == CV_8U)
45+ if (depth == CV_8U)
6346 {
6447 uchar half = UCHAR_MAX/2 ;
6548 maxd = (unsigned char )rng.uniform (half+32 , UCHAR_MAX);
6649 mind = (unsigned char )rng.uniform (0 , half-32 );
6750 }
68- else if (type == CV_8S)
51+ else if (depth == CV_8S)
6952 {
7053 maxd = (char )rng.uniform (32 , CHAR_MAX);
7154 mind = (char )rng.uniform (CHAR_MIN, -32 );
7255 }
73- else if (type == CV_16U)
56+ else if (depth == CV_16U)
7457 {
7558 ushort half = USHRT_MAX/2 ;
7659 maxd = (unsigned int )rng.uniform (half+32 , USHRT_MAX);
7760 mind = (unsigned int )rng.uniform (0 , half-32 );
7861 }
79- else if (type == CV_16S)
62+ else if (depth == CV_16S)
8063 {
8164 maxd = rng.uniform (32 , SHRT_MAX);
8265 mind = rng.uniform (SHRT_MIN, -32 );
8366 }
84- else if (type == CV_32S)
67+ else if (depth == CV_32S)
8568 {
8669 maxd = rng.uniform (32 , INT_MAX);
8770 mind = rng.uniform (INT_MIN, -32 );
8871 }
89- else if (type == CV_32F)
72+ else
9073 {
91- maxd = rng.uniform (32 .0f , FLT_MAX);
92- mind = rng.uniform (-FLT_MAX, -32 .0f );
93- }
94- else if (type == CV_64F)
95- {
96- maxd = rng.uniform (32.0 , DBL_MAX);
97- mind = rng.uniform (-DBL_MAX, -32.0 );
74+ ASSERT_TRUE ( (depth == CV_32F)||(depth == CV_64F) ) << " Unsupported depth" ;
75+ const double harf = 0.5 ;
76+ const double bias = 0.125 ; // = 32/256 (Like CV_8U)
77+ maxd = rng.uniform (harf + bias, 1.0 );
78+ mind = rng.uniform (0.0 , harf - bias );
9879 }
9980
10081 fgbg->setMinVal (mind);
10182 fgbg->setMaxVal (maxd);
10283
103- Mat simImage = Mat::zeros (height, width, channelsAndType);
104- int numLearningFrames = 120 ;
84+ Mat simImage (height, width, mtype);
85+ Mat fgmask;
86+
87+ const Mat fullbg (height, width, CV_8UC1, cv::Scalar (0 )); // all background.
88+
89+ const int numLearningFrames = 120 ;
10590 for (int i = 0 ; i < numLearningFrames; ++i)
10691 {
10792 /* *
@@ -113,27 +98,21 @@ void CV_BackgroundSubtractorTest::run(int)
11398 * Feed simulated images into background subtractor
11499 */
115100 fgbg->apply (simImage,fgmask);
116- Mat fullbg = Mat::zeros (simImage.rows , simImage.cols , CV_8U);
117101
118- // ! fgmask should be entirely background during training
119- code = cvtest::cmpEps2 ( ts, fgmask, fullbg, 0 , false , " The training foreground mask" );
120- if (code < 0 )
121- ts->set_failed_test_info ( code );
102+ EXPECT_EQ (cv::norm (fgmask, fullbg, NORM_INF), 0 ) << " foreground mask should be entirely background during training" ;
122103 }
123104 // ! generate last image, distinct from training images
124105 rng.fill (simImage, RNG::UNIFORM, mind, maxd);
125-
126106 fgbg->apply (simImage,fgmask);
127- // ! now fgmask should be entirely foreground
128- Mat fullfg = 255 *Mat::ones (simImage.rows , simImage.cols , CV_8U);
129- code = cvtest::cmpEps2 ( ts, fgmask, fullfg, 255 , false , " The final foreground mask" );
130- if (code < 0 )
131- {
132- ts->set_failed_test_info ( code );
133- }
134107
108+ const Mat fullfg (height, width, CV_8UC1, cv::Scalar (255 )); // all foreground.
109+ EXPECT_EQ (cv::norm (fgmask, fullfg, NORM_INF), 0 ) << " foreground mask should be entirely foreground finally" ;
135110}
136111
137- TEST (VIDEO_BGSUBGMG, accuracy) { CV_BackgroundSubtractorTest test; test.safe_run (); }
112+ INSTANTIATE_TEST_CASE_P (/* */ ,
113+ bgsubgmg_allTypes,
114+ testing::Combine (
115+ testing::Values (CV_8U, CV_8S, CV_16U, CV_16S, CV_32S, CV_32F, CV_64F),
116+ testing::Values(1 ,2 ,3 ,4 )));
138117
139118}} // namespace
0 commit comments