Skip to content

Commit aa7a964

Browse files
mshabuninalalek
authored andcommitted
Merge pull request opencv#10868 from mshabunin:sample-bgsegm
* Samples: reworked bgfg_bgsegm * fixup! Samples: reworked bgfg_bgsegm
1 parent 73a8369 commit aa7a964

File tree

1 file changed

+84
-78
lines changed

1 file changed

+84
-78
lines changed

samples/cpp/bgfg_segm.cpp

Lines changed: 84 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,111 +1,117 @@
11
#include "opencv2/core.hpp"
2-
#include <opencv2/core/utility.hpp>
32
#include "opencv2/imgproc.hpp"
4-
#include "opencv2/video/background_segm.hpp"
3+
#include "opencv2/video.hpp"
54
#include "opencv2/videoio.hpp"
65
#include "opencv2/highgui.hpp"
7-
#include <stdio.h>
6+
#include <iostream>
87

98
using namespace std;
109
using namespace cv;
1110

12-
static void help()
13-
{
14-
printf("\nDo background segmentation, especially demonstrating the use of cvUpdateBGStatModel().\n"
15-
"Learns the background at the start and then segments.\n"
16-
"Learning is togged by the space key. Will read from file or camera\n"
17-
"Usage: \n"
18-
" ./bgfg_segm [--camera]=<use camera, if this key is present>, [--file_name]=<path to movie file> \n\n");
19-
}
20-
21-
const char* keys =
22-
{
23-
"{c camera | | use camera or not}"
24-
"{m method |mog2 | method (knn or mog2) }"
25-
"{s smooth | | smooth the mask }"
26-
"{fn file_name|../data/tree.avi | movie file }"
27-
};
28-
29-
//this is a sample for foreground detection functions
3011
int main(int argc, const char** argv)
3112
{
32-
help();
33-
13+
const String keys = "{c camera||use video stream from camera (default is NO)}"
14+
"{fn file_name|../data/tree.avi|video file}"
15+
"{m method|mog2|method: background subtraction algorithm ('knn', 'mog2')}"
16+
"{h help||show help message}";
3417
CommandLineParser parser(argc, argv, keys);
18+
parser.about("This sample demonstrates background segmentation.");
19+
if (parser.has("help"))
20+
{
21+
parser.printMessage();
22+
return 0;
23+
}
3524
bool useCamera = parser.has("camera");
36-
bool smoothMask = parser.has("smooth");
37-
string file = parser.get<string>("file_name");
38-
string method = parser.get<string>("method");
39-
VideoCapture cap;
40-
bool update_bg_model = true;
25+
String file = parser.get<String>("file_name");
26+
String method = parser.get<String>("method");
27+
if (!parser.check())
28+
{
29+
parser.printErrors();
30+
return 1;
31+
}
4132

42-
if( useCamera )
33+
VideoCapture cap;
34+
if (useCamera)
4335
cap.open(0);
4436
else
4537
cap.open(file.c_str());
46-
47-
parser.printMessage();
48-
49-
if( !cap.isOpened() )
38+
if (!cap.isOpened())
5039
{
51-
printf("can not open camera or video file\n");
52-
return -1;
40+
cout << "Can not open video stream: '" << (useCamera ? "<camera 0>" : file) << "'" << endl;
41+
return 2;
5342
}
5443

55-
namedWindow("image", WINDOW_NORMAL);
56-
namedWindow("foreground mask", WINDOW_NORMAL);
57-
namedWindow("foreground image", WINDOW_NORMAL);
58-
namedWindow("mean background image", WINDOW_NORMAL);
59-
60-
Ptr<BackgroundSubtractor> bg_model = method == "knn" ?
61-
createBackgroundSubtractorKNN().dynamicCast<BackgroundSubtractor>() :
62-
createBackgroundSubtractorMOG2().dynamicCast<BackgroundSubtractor>();
44+
Ptr<BackgroundSubtractor> model;
45+
if (method == "knn")
46+
model = createBackgroundSubtractorKNN();
47+
else if (method == "mog2")
48+
model = createBackgroundSubtractorMOG2();
49+
if (!model)
50+
{
51+
cout << "Can not create background model using provided method: '" << method << "'" << endl;
52+
return 3;
53+
}
6354

64-
Mat img0, img, fgmask, fgimg;
55+
cout << "Press <space> to toggle background model update" << endl;
56+
cout << "Press 's' to toggle foreground mask smoothing" << endl;
57+
cout << "Press ESC or 'q' to exit" << endl;
58+
bool doUpdateModel = true;
59+
bool doSmoothMask = false;
6560

66-
for(;;)
61+
Mat inputFrame, frame, foregroundMask, foreground, background;
62+
for (;;)
6763
{
68-
cap >> img0;
69-
70-
if( img0.empty() )
64+
// prepare input frame
65+
cap >> inputFrame;
66+
if (inputFrame.empty())
67+
{
68+
cout << "Finished reading: empty frame" << endl;
7169
break;
70+
}
71+
const Size scaledSize(640, 640 * inputFrame.rows / inputFrame.cols);
72+
resize(inputFrame, frame, scaledSize, 0, 0, INTER_LINEAR);
7273

73-
resize(img0, img, Size(640, 640*img0.rows/img0.cols), 0, 0, INTER_LINEAR_EXACT);
74+
// pass the frame to background model
75+
model->apply(frame, foregroundMask, doUpdateModel ? -1 : 0);
7476

75-
if( fgimg.empty() )
76-
fgimg.create(img.size(), img.type());
77+
// show processed frame
78+
imshow("image", frame);
7779

78-
//update the model
79-
bg_model->apply(img, fgmask, update_bg_model ? -1 : 0);
80-
if( smoothMask )
80+
// show foreground image and mask (with optional smoothing)
81+
if (doSmoothMask)
8182
{
82-
GaussianBlur(fgmask, fgmask, Size(11, 11), 3.5, 3.5);
83-
threshold(fgmask, fgmask, 10, 255, THRESH_BINARY);
83+
GaussianBlur(foregroundMask, foregroundMask, Size(11, 11), 3.5, 3.5);
84+
threshold(foregroundMask, foregroundMask, 10, 255, THRESH_BINARY);
8485
}
85-
86-
fgimg = Scalar::all(0);
87-
img.copyTo(fgimg, fgmask);
88-
89-
Mat bgimg;
90-
bg_model->getBackgroundImage(bgimg);
91-
92-
imshow("image", img);
93-
imshow("foreground mask", fgmask);
94-
imshow("foreground image", fgimg);
95-
if(!bgimg.empty())
96-
imshow("mean background image", bgimg );
97-
98-
char k = (char)waitKey(30);
99-
if( k == 27 ) break;
100-
if( k == ' ' )
86+
if (foreground.empty())
87+
foreground.create(scaledSize, frame.type());
88+
foreground = Scalar::all(0);
89+
frame.copyTo(foreground, foregroundMask);
90+
imshow("foreground mask", foregroundMask);
91+
imshow("foreground image", foreground);
92+
93+
// show background image
94+
model->getBackgroundImage(background);
95+
if (!background.empty())
96+
imshow("mean background image", background );
97+
98+
// interact with user
99+
const char key = (char)waitKey(30);
100+
if (key == 27 || key == 'q') // ESC
101+
{
102+
cout << "Exit requested" << endl;
103+
break;
104+
}
105+
else if (key == ' ')
101106
{
102-
update_bg_model = !update_bg_model;
103-
if(update_bg_model)
104-
printf("Background update is on\n");
105-
else
106-
printf("Background update is off\n");
107+
doUpdateModel = !doUpdateModel;
108+
cout << "Toggle background update: " << (doUpdateModel ? "ON" : "OFF") << endl;
109+
}
110+
else if (key == 's')
111+
{
112+
doSmoothMask = !doSmoothMask;
113+
cout << "Toggle foreground mask smoothing: " << (doSmoothMask ? "ON" : "OFF") << endl;
107114
}
108115
}
109-
110116
return 0;
111117
}

0 commit comments

Comments
 (0)