Commit aa7a9641 authored by Maksim Shabunin's avatar Maksim Shabunin Committed by Alexander Alekhin

Merge pull request #10868 from mshabunin:sample-bgsegm

* Samples: reworked bgfg_bgsegm

* fixup! Samples: reworked bgfg_bgsegm
parent 73a83696
#include "opencv2/core.hpp"
#include <opencv2/core/utility.hpp>
#include "opencv2/imgproc.hpp"
#include "opencv2/video/background_segm.hpp"
#include "opencv2/video.hpp"
#include "opencv2/videoio.hpp"
#include "opencv2/highgui.hpp"
#include <stdio.h>
#include <iostream>
using namespace std;
using namespace cv;
static void help()
{
printf("\nDo background segmentation, especially demonstrating the use of cvUpdateBGStatModel().\n"
"Learns the background at the start and then segments.\n"
"Learning is togged by the space key. Will read from file or camera\n"
"Usage: \n"
" ./bgfg_segm [--camera]=<use camera, if this key is present>, [--file_name]=<path to movie file> \n\n");
}
const char* keys =
{
"{c camera | | use camera or not}"
"{m method |mog2 | method (knn or mog2) }"
"{s smooth | | smooth the mask }"
"{fn file_name|../data/tree.avi | movie file }"
};
//this is a sample for foreground detection functions
int main(int argc, const char** argv)
{
help();
const String keys = "{c camera||use video stream from camera (default is NO)}"
"{fn file_name|../data/tree.avi|video file}"
"{m method|mog2|method: background subtraction algorithm ('knn', 'mog2')}"
"{h help||show help message}";
CommandLineParser parser(argc, argv, keys);
parser.about("This sample demonstrates background segmentation.");
if (parser.has("help"))
{
parser.printMessage();
return 0;
}
bool useCamera = parser.has("camera");
bool smoothMask = parser.has("smooth");
string file = parser.get<string>("file_name");
string method = parser.get<string>("method");
VideoCapture cap;
bool update_bg_model = true;
String file = parser.get<String>("file_name");
String method = parser.get<String>("method");
if (!parser.check())
{
parser.printErrors();
return 1;
}
if( useCamera )
VideoCapture cap;
if (useCamera)
cap.open(0);
else
cap.open(file.c_str());
parser.printMessage();
if( !cap.isOpened() )
if (!cap.isOpened())
{
printf("can not open camera or video file\n");
return -1;
cout << "Can not open video stream: '" << (useCamera ? "<camera 0>" : file) << "'" << endl;
return 2;
}
namedWindow("image", WINDOW_NORMAL);
namedWindow("foreground mask", WINDOW_NORMAL);
namedWindow("foreground image", WINDOW_NORMAL);
namedWindow("mean background image", WINDOW_NORMAL);
Ptr<BackgroundSubtractor> bg_model = method == "knn" ?
createBackgroundSubtractorKNN().dynamicCast<BackgroundSubtractor>() :
createBackgroundSubtractorMOG2().dynamicCast<BackgroundSubtractor>();
Ptr<BackgroundSubtractor> model;
if (method == "knn")
model = createBackgroundSubtractorKNN();
else if (method == "mog2")
model = createBackgroundSubtractorMOG2();
if (!model)
{
cout << "Can not create background model using provided method: '" << method << "'" << endl;
return 3;
}
Mat img0, img, fgmask, fgimg;
cout << "Press <space> to toggle background model update" << endl;
cout << "Press 's' to toggle foreground mask smoothing" << endl;
cout << "Press ESC or 'q' to exit" << endl;
bool doUpdateModel = true;
bool doSmoothMask = false;
for(;;)
Mat inputFrame, frame, foregroundMask, foreground, background;
for (;;)
{
cap >> img0;
if( img0.empty() )
// prepare input frame
cap >> inputFrame;
if (inputFrame.empty())
{
cout << "Finished reading: empty frame" << endl;
break;
}
const Size scaledSize(640, 640 * inputFrame.rows / inputFrame.cols);
resize(inputFrame, frame, scaledSize, 0, 0, INTER_LINEAR);
resize(img0, img, Size(640, 640*img0.rows/img0.cols), 0, 0, INTER_LINEAR_EXACT);
// pass the frame to background model
model->apply(frame, foregroundMask, doUpdateModel ? -1 : 0);
if( fgimg.empty() )
fgimg.create(img.size(), img.type());
// show processed frame
imshow("image", frame);
//update the model
bg_model->apply(img, fgmask, update_bg_model ? -1 : 0);
if( smoothMask )
// show foreground image and mask (with optional smoothing)
if (doSmoothMask)
{
GaussianBlur(fgmask, fgmask, Size(11, 11), 3.5, 3.5);
threshold(fgmask, fgmask, 10, 255, THRESH_BINARY);
GaussianBlur(foregroundMask, foregroundMask, Size(11, 11), 3.5, 3.5);
threshold(foregroundMask, foregroundMask, 10, 255, THRESH_BINARY);
}
fgimg = Scalar::all(0);
img.copyTo(fgimg, fgmask);
Mat bgimg;
bg_model->getBackgroundImage(bgimg);
imshow("image", img);
imshow("foreground mask", fgmask);
imshow("foreground image", fgimg);
if(!bgimg.empty())
imshow("mean background image", bgimg );
char k = (char)waitKey(30);
if( k == 27 ) break;
if( k == ' ' )
if (foreground.empty())
foreground.create(scaledSize, frame.type());
foreground = Scalar::all(0);
frame.copyTo(foreground, foregroundMask);
imshow("foreground mask", foregroundMask);
imshow("foreground image", foreground);
// show background image
model->getBackgroundImage(background);
if (!background.empty())
imshow("mean background image", background );
// interact with user
const char key = (char)waitKey(30);
if (key == 27 || key == 'q') // ESC
{
cout << "Exit requested" << endl;
break;
}
else if (key == ' ')
{
update_bg_model = !update_bg_model;
if(update_bg_model)
printf("Background update is on\n");
else
printf("Background update is off\n");
doUpdateModel = !doUpdateModel;
cout << "Toggle background update: " << (doUpdateModel ? "ON" : "OFF") << endl;
}
else if (key == 's')
{
doSmoothMask = !doSmoothMask;
cout << "Toggle foreground mask smoothing: " << (doSmoothMask ? "ON" : "OFF") << endl;
}
}
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment