Commit 4bea70a6 authored by catree's avatar catree

Update background subtraction tutorial with Java and Python codes.

parent defeda2f
...@@ -6,6 +6,8 @@ tracking and foreground extractions. ...@@ -6,6 +6,8 @@ tracking and foreground extractions.
- @subpage tutorial_background_subtraction - @subpage tutorial_background_subtraction
*Languages:* C++, Java, Python
*Compatibility:* \> OpenCV 2.4.6 *Compatibility:* \> OpenCV 2.4.6
*Author:* Domenico Daniele Bloisi *Author:* Domenico Daniele Bloisi
......
...@@ -4,180 +4,84 @@ ...@@ -4,180 +4,84 @@
* @author Domenico D. Bloisi * @author Domenico D. Bloisi
*/ */
//opencv
#include "opencv2/imgcodecs.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/videoio.hpp"
#include <opencv2/highgui.hpp>
#include <opencv2/video.hpp>
//C
#include <stdio.h>
//C++
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/video.hpp>
using namespace cv; using namespace cv;
using namespace std; using namespace std;
// Global variables const char* params
Mat frame; //current frame = "{ help h | | Print usage }"
Mat fgMaskMOG2; //fg mask fg mask generated by MOG2 method "{ input | ../data/vtest.avi | Path to a video or a sequence of image }"
Ptr<BackgroundSubtractor> pMOG2; //MOG2 Background subtractor "{ algo | MOG2 | Background subtraction method (KNN, MOG2) }";
char keyboard; //input from keyboard
/** Function Headers */
void help();
void processVideo(char* videoFilename);
void processImages(char* firstFrameFilename);
void help()
{
cout
<< "--------------------------------------------------------------------------" << endl
<< "This program shows how to use background subtraction methods provided by " << endl
<< " OpenCV. You can process both videos (-vid) and images (-img)." << endl
<< endl
<< "Usage:" << endl
<< "./bg_sub {-vid <video filename>|-img <image filename>}" << endl
<< "for example: ./bg_sub -vid video.avi" << endl
<< "or: ./bg_sub -img /data/images/1.png" << endl
<< "--------------------------------------------------------------------------" << endl
<< endl;
}
/**
* @function main
*/
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
CommandLineParser parser(argc, argv, params);
parser.about( "This program shows how to use background subtraction methods provided by "
" OpenCV. You can process both videos and images.\n" );
if (parser.has("help"))
{
//print help information //print help information
help(); parser.printMessage();
//check for the input parameter correctness
if(argc != 3) {
cerr <<"Incorret input list" << endl;
cerr <<"exiting..." << endl;
return EXIT_FAILURE;
} }
//create GUI windows //! [create]
namedWindow("Frame");
namedWindow("FG Mask MOG 2");
//create Background Subtractor objects //create Background Subtractor objects
pMOG2 = createBackgroundSubtractorMOG2(); //MOG2 approach Ptr<BackgroundSubtractor> pBackSub;
if (parser.get<String>("algo") == "MOG2")
if(strcmp(argv[1], "-vid") == 0) { pBackSub = createBackgroundSubtractorMOG2();
//input data coming from a video else
processVideo(argv[2]); pBackSub = createBackgroundSubtractorKNN();
} //! [create]
else if(strcmp(argv[1], "-img") == 0) {
//input data coming from a sequence of images
processImages(argv[2]);
}
else {
//error in reading input parameters
cerr <<"Please, check the input parameters." << endl;
cerr <<"Exiting..." << endl;
return EXIT_FAILURE;
}
//destroy GUI windows
destroyAllWindows();
return EXIT_SUCCESS;
}
/** //! [capture]
* @function processVideo VideoCapture capture(parser.get<String>("input"));
*/ if (!capture.isOpened()){
void processVideo(char* videoFilename) {
//create the capture object
VideoCapture capture(videoFilename);
if(!capture.isOpened()){
//error in opening the video input //error in opening the video input
cerr << "Unable to open video file: " << videoFilename << endl; cerr << "Unable to open: " << parser.get<String>("input") << endl;
exit(EXIT_FAILURE); return 0;
}
//read input data. ESC or 'q' for quitting
keyboard = 0;
while( keyboard != 'q' && keyboard != 27 ){
//read the current frame
if(!capture.read(frame)) {
cerr << "Unable to read next frame." << endl;
cerr << "Exiting..." << endl;
exit(EXIT_FAILURE);
} }
//! [capture]
Mat frame, fgMask;
while (true) {
capture >> frame;
if (frame.empty())
break;
//! [apply]
//update the background model //update the background model
pMOG2->apply(frame, fgMaskMOG2); pBackSub->apply(frame, fgMask);
//! [apply]
//! [display_frame_number]
//get the frame number and write it on the current frame //get the frame number and write it on the current frame
stringstream ss;
rectangle(frame, cv::Point(10, 2), cv::Point(100,20), rectangle(frame, cv::Point(10, 2), cv::Point(100,20),
cv::Scalar(255,255,255), -1); cv::Scalar(255,255,255), -1);
stringstream ss;
ss << capture.get(CAP_PROP_POS_FRAMES); ss << capture.get(CAP_PROP_POS_FRAMES);
string frameNumberString = ss.str(); string frameNumberString = ss.str();
putText(frame, frameNumberString.c_str(), cv::Point(15, 15), putText(frame, frameNumberString.c_str(), cv::Point(15, 15),
FONT_HERSHEY_SIMPLEX, 0.5 , cv::Scalar(0,0,0)); FONT_HERSHEY_SIMPLEX, 0.5 , cv::Scalar(0,0,0));
//show the current frame and the fg masks //! [display_frame_number]
imshow("Frame", frame);
imshow("FG Mask MOG 2", fgMaskMOG2);
//get the input from the keyboard
keyboard = (char)waitKey( 30 );
}
//delete capture object
capture.release();
}
/** //! [show]
* @function processImages
*/
void processImages(char* fistFrameFilename) {
//read the first file of the sequence
frame = imread(fistFrameFilename);
if(frame.empty()){
//error in opening the first image
cerr << "Unable to open first image frame: " << fistFrameFilename << endl;
exit(EXIT_FAILURE);
}
//current image filename
string fn(fistFrameFilename);
//read input data. ESC or 'q' for quitting
keyboard = 0;
while( keyboard != 'q' && keyboard != 27 ){
//update the background model
pMOG2->apply(frame, fgMaskMOG2);
//get the frame number and write it on the current frame
size_t index = fn.find_last_of("/");
if(index == string::npos) {
index = fn.find_last_of("\\");
}
size_t index2 = fn.find_last_of(".");
string prefix = fn.substr(0,index+1);
string suffix = fn.substr(index2);
string frameNumberString = fn.substr(index+1, index2-index-1);
istringstream iss(frameNumberString);
int frameNumber = 0;
iss >> frameNumber;
rectangle(frame, cv::Point(10, 2), cv::Point(100,20),
cv::Scalar(255,255,255), -1);
putText(frame, frameNumberString.c_str(), cv::Point(15, 15),
FONT_HERSHEY_SIMPLEX, 0.5 , cv::Scalar(0,0,0));
//show the current frame and the fg masks //show the current frame and the fg masks
imshow("Frame", frame); imshow("Frame", frame);
imshow("FG Mask MOG 2", fgMaskMOG2); imshow("FG Mask", fgMask);
//! [show]
//get the input from the keyboard //get the input from the keyboard
keyboard = (char)waitKey( 30 ); int keyboard = waitKey(30);
//search for the next image in the sequence if (keyboard == 'q' || keyboard == 27)
ostringstream oss; break;
oss << (frameNumber + 1);
string nextFrameNumberString = oss.str();
string nextFrameFilename = prefix + nextFrameNumberString + suffix;
//read the next frame
frame = imread(nextFrameFilename);
if(frame.empty()){
//error in opening the next image in the sequence
cerr << "Unable to open image frame: " << nextFrameFilename << endl;
exit(EXIT_FAILURE);
}
//update the path of the current frame
fn.assign(nextFrameFilename);
} }
return 0;
} }
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.highgui.HighGui;
import org.opencv.imgproc.Imgproc;
import org.opencv.video.BackgroundSubtractor;
import org.opencv.video.Video;
import org.opencv.videoio.VideoCapture;
import org.opencv.videoio.Videoio;
class BackgroundSubtraction {
public void run(String[] args) {
String input = args.length > 0 ? args[0] : "../data/vtest.avi";
boolean useMOG2 = args.length > 1 ? args[1] == "MOG2" : true;
//! [create]
BackgroundSubtractor backSub;
if (useMOG2) {
backSub = Video.createBackgroundSubtractorMOG2();
} else {
backSub = Video.createBackgroundSubtractorKNN();
}
//! [create]
//! [capture]
VideoCapture capture = new VideoCapture(input);
if (!capture.isOpened()) {
System.err.println("Unable to open: " + input);
System.exit(0);
}
//! [capture]
Mat frame = new Mat(), fgMask = new Mat();
while (true) {
capture.read(frame);
if (frame.empty()) {
break;
}
//! [apply]
// update the background model
backSub.apply(frame, fgMask);
//! [apply]
//! [display_frame_number]
// get the frame number and write it on the current frame
Imgproc.rectangle(frame, new Point(10, 2), new Point(100, 20), new Scalar(255, 255, 255), -1);
String frameNumberString = String.format("%d", (int)capture.get(Videoio.CAP_PROP_POS_FRAMES));
Imgproc.putText(frame, frameNumberString, new Point(15, 15), Core.FONT_HERSHEY_SIMPLEX, 0.5,
new Scalar(0, 0, 0));
//! [display_frame_number]
//! [show]
// show the current frame and the fg masks
HighGui.imshow("Frame", frame);
HighGui.imshow("FG Mask", fgMask);
//! [show]
// get the input from the keyboard
int keyboard = HighGui.waitKey(30);
if (keyboard == 'q' || keyboard == 27) {
break;
}
}
HighGui.waitKey();
System.exit(0);
}
}
public class BackgroundSubtractionDemo {
public static void main(String[] args) {
// Load the native OpenCV library
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
new BackgroundSubtraction().run(args);
}
}
from __future__ import print_function
import cv2 as cv
import argparse
parser = argparse.ArgumentParser(description='This program shows how to use background subtraction methods provided by \
OpenCV. You can process both videos and images.')
parser.add_argument('--input', type=str, help='Path to a video or a sequence of image.', default='../data/vtest.avi')
parser.add_argument('--algo', type=str, help='Background subtraction method (KNN, MOG2).', default='MOG2')
args = parser.parse_args()
## [create]
#create Background Subtractor objects
if args.algo == 'MOG2':
backSub = cv.createBackgroundSubtractorMOG2()
else:
backSub = cv.createBackgroundSubtractorKNN()
## [create]
## [capture]
capture = cv.VideoCapture(args.input)
if not capture.isOpened:
print('Unable to open: ' + args.input)
exit(0)
## [capture]
while True:
ret, frame = capture.read()
if frame is None:
break
## [apply]
#update the background model
fgMask = backSub.apply(frame)
## [apply]
## [display_frame_number]
#get the frame number and write it on the current frame
cv.rectangle(frame, (10, 2), (100,20), (255,255,255), -1)
cv.putText(frame, str(capture.get(cv.CAP_PROP_POS_FRAMES)), (15, 15),
cv.FONT_HERSHEY_SIMPLEX, 0.5 , (0,0,0))
## [display_frame_number]
## [show]
#show the current frame and the fg masks
cv.imshow('Frame', frame)
cv.imshow('FG Mask', fgMask)
## [show]
keyboard = cv.waitKey(30)
if keyboard == 'q' or keyboard == 27:
break
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