Doxygen tutorials: cpp done

This commit is contained in:
Maksim Shabunin
2014-11-28 16:21:28 +03:00
parent c5536534d8
commit 36a04ef8de
92 changed files with 2142 additions and 3691 deletions

View File

@@ -9,12 +9,12 @@ How to Use Background Subtraction Methods {#tutorial_background_subtraction}
general, everything that can be considered as background given the characteristics of the
observed scene.
![image](images/Background_Subtraction_Tutorial_Scheme.png)
![](images/Background_Subtraction_Tutorial_Scheme.png)
- Background modeling consists of two main steps:
1. Background Initialization;
2. Background Update.
-# Background Initialization;
-# Background Update.
In the first step, an initial model of the background is computed, while in the second step that
model is updated in order to adapt to possible changes in the scene.
@@ -28,11 +28,11 @@ Goals
In this tutorial you will learn how to:
1. Read data from videos by using @ref cv::VideoCapture or image sequences by using @ref
-# Read data from videos by using @ref cv::VideoCapture or image sequences by using @ref
cv::imread ;
2. Create and update the background model by using @ref cv::BackgroundSubtractor class;
3. Get and show the foreground mask by using @ref cv::imshow ;
4. Save the output by using @ref cv::imwrite to quantitatively evaluate the results.
-# Create and update the background model by using @ref cv::BackgroundSubtractor class;
-# Get and show the foreground mask by using @ref cv::imshow ;
-# Save the output by using @ref cv::imwrite to quantitatively evaluate the results.
Code
----
@@ -40,201 +40,28 @@ Code
In the following you can find the source code. We will let the user chose to process either a video
file or a sequence of images.
-
Two different methods are used to generate two foreground masks:
1. @ref cv::bgsegm::BackgroundSubtractorMOG
2. @ref cv::bgsegm::BackgroundSubtractorMOG2
Two different methods are used to generate two foreground masks:
-# @ref cv::bgsegm::BackgroundSubtractorMOG
-# @ref cv::BackgroundSubtractorMOG2
The results as well as the input data are shown on the screen.
@code{.cpp}
//opencv
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/video/background_segm.hpp>
//C
#include <stdio.h>
//C++
#include <iostream>
#include <sstream>
The source file can be downloaded [here ](samples/cpp/tutorial_code/video/bg_sub.cpp).
using namespace cv;
using namespace std;
//global variables
Mat frame; //current frame
Mat fgMaskMOG; //fg mask generated by MOG method
Mat fgMaskMOG2; //fg mask fg mask generated by MOG2 method
Ptr<BackgroundSubtractor> pMOG; //MOG Background subtractor
Ptr<BackgroundSubtractor> pMOG2; //MOG2 Background subtractor
int keyboard;
//function declarations
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
<< "./bs {-vid <video filename>|-img <image filename>}" << endl
<< "for example: ./bs -vid video.avi" << endl
<< "or: ./bs -img /data/images/1.png" << endl
<< "--------------------------------------------------------------------------" << endl
<< endl;
}
int main(int argc, char* argv[])
{
//print help information
help();
//check for the input parameter correctness
if(argc != 3) {
cerr <<"Incorret input list" << endl;
cerr <<"exiting..." << endl;
return EXIT_FAILURE;
}
//create GUI windows
namedWindow("Frame");
namedWindow("FG Mask MOG");
namedWindow("FG Mask MOG 2");
//create Background Subtractor objects
pMOG = createBackgroundSubtractorMOG(); //MOG approach
pMOG2 = createBackgroundSubtractorMOG2(); //MOG2 approach
if(strcmp(argv[1], "-vid") == 0) {
//input data coming from a video
processVideo(argv[2]);
}
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;
}
void processVideo(char* videoFilename) {
//create the capture object
VideoCapture capture(videoFilename);
if(!capture.isOpened()){
//error in opening the video input
cerr << "Unable to open video file: " << videoFilename << endl;
exit(EXIT_FAILURE);
}
//read input data. ESC or 'q' for quitting
while( (char)keyboard != 'q' && (char)keyboard != 27 ){
//read the current frame
if(!capture.read(frame)) {
cerr << "Unable to read next frame." << endl;
cerr << "Exiting..." << endl;
exit(EXIT_FAILURE);
}
//update the background model
pMOG->apply(frame, fgMaskMOG);
pMOG2->apply(frame, fgMaskMOG2);
//get the frame number and write it on the current frame
stringstream ss;
rectangle(frame, cv::Point(10, 2), cv::Point(100,20),
cv::Scalar(255,255,255), -1);
ss << capture.get(CAP_PROP_POS_FRAMES);
string frameNumberString = ss.str();
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
imshow("Frame", frame);
imshow("FG Mask MOG", fgMaskMOG);
imshow("FG Mask MOG 2", fgMaskMOG2);
//get the input from the keyboard
keyboard = waitKey( 30 );
}
//delete capture object
capture.release();
}
void processImages(char* fistFrameFilename) {
//read the first file of the sequence
frame = imread(fistFrameFilename);
if(!frame.data){
//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
while( (char)keyboard != 'q' && (char)keyboard != 27 ){
//update the background model
pMOG->apply(frame, fgMaskMOG);
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
imshow("Frame", frame);
imshow("FG Mask MOG", fgMaskMOG);
imshow("FG Mask MOG 2", fgMaskMOG2);
//get the input from the keyboard
keyboard = waitKey( 30 );
//search for the next image in the sequence
ostringstream oss;
oss << (frameNumber + 1);
string nextFrameNumberString = oss.str();
string nextFrameFilename = prefix + nextFrameNumberString + suffix;
//read the next frame
frame = imread(nextFrameFilename);
if(!frame.data){
//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);
}
}
@endcode
- The source file can be downloaded [here ](samples/cpp/tutorial_code/video/bg_sub.cpp).
@includelineno samples/cpp/tutorial_code/video/bg_sub.cpp
Explanation
-----------
We discuss the main parts of the above code:
1. First, three Mat objects are allocated to store the current frame and two foreground masks,
-# First, three Mat objects are allocated to store the current frame and two foreground masks,
obtained by using two different BS algorithms.
@code{.cpp}
Mat frame; //current frame
Mat fgMaskMOG; //fg mask generated by MOG method
Mat fgMaskMOG2; //fg mask fg mask generated by MOG2 method
@endcode
2. Two @ref cv::BackgroundSubtractor objects will be used to generate the foreground masks. In this
-# Two @ref cv::BackgroundSubtractor objects will be used to generate the foreground masks. In this
example, default parameters are used, but it is also possible to declare specific parameters in
the create function.
@code{.cpp}
@@ -245,8 +72,7 @@ We discuss the main parts of the above code:
pMOG = createBackgroundSubtractorMOG(); //MOG approach
pMOG2 = createBackgroundSubtractorMOG2(); //MOG2 approach
@endcode
3. The command line arguments are analysed. The user can chose between two options:
-# The command line arguments are analysed. The user can chose between two options:
- video files (by choosing the option -vid);
- image sequences (by choosing the option -img).
@code{.cpp}
@@ -259,7 +85,7 @@ We discuss the main parts of the above code:
processImages(argv[2]);
}
@endcode
4. Suppose you want to process a video file. The video is read until the end is reached or the user
-# Suppose you want to process a video file. The video is read until the end is reached or the user
presses the button 'q' or the button 'ESC'.
@code{.cpp}
while( (char)keyboard != 'q' && (char)keyboard != 27 ){
@@ -270,7 +96,7 @@ We discuss the main parts of the above code:
exit(EXIT_FAILURE);
}
@endcode
5. Every frame is used both for calculating the foreground mask and for updating the background. If
-# Every frame is used both for calculating the foreground mask and for updating the background. If
you want to change the learning rate used for updating the background model, it is possible to
set a specific learning rate by passing a third parameter to the 'apply' method.
@code{.cpp}
@@ -278,7 +104,7 @@ We discuss the main parts of the above code:
pMOG->apply(frame, fgMaskMOG);
pMOG2->apply(frame, fgMaskMOG2);
@endcode
6. The current frame number can be extracted from the @ref cv::VideoCapture object and stamped in
-# The current frame number can be extracted from the @ref cv::VideoCapture object and stamped in
the top left corner of the current frame. A white rectangle is used to highlight the black
colored frame number.
@code{.cpp}
@@ -291,14 +117,14 @@ We discuss the main parts of the above code:
putText(frame, frameNumberString.c_str(), cv::Point(15, 15),
FONT_HERSHEY_SIMPLEX, 0.5 , cv::Scalar(0,0,0));
@endcode
7. We are ready to show the current input frame and the results.
-# We are ready to show the current input frame and the results.
@code{.cpp}
//show the current frame and the fg masks
imshow("Frame", frame);
imshow("FG Mask MOG", fgMaskMOG);
imshow("FG Mask MOG 2", fgMaskMOG2);
@endcode
8. The same operations listed above can be performed using a sequence of images as input. The
-# The same operations listed above can be performed using a sequence of images as input. The
processImage function is called and, instead of using a @ref cv::VideoCapture object, the images
are read by using @ref cv::imread , after individuating the correct path for the next frame to
read.
@@ -338,7 +164,7 @@ Results
@endcode
The output of the program will look as the following:
![image](images/Background_Subtraction_Tutorial_Result_1.png)
![](images/Background_Subtraction_Tutorial_Result_1.png)
- The video file Video_001.avi is part of the [Background Models Challenge
(BMC)](http://bmc.univ-bpclermont.fr/) data set and it can be downloaded from the following link
@@ -350,7 +176,7 @@ Results
@endcode
The output of the program will look as the following:
![image](images/Background_Subtraction_Tutorial_Result_2.png)
![](images/Background_Subtraction_Tutorial_Result_2.png)
- The sequence of images used in this example is part of the [Background Models Challenge
(BMC)](http://bmc.univ-bpclermont.fr/) dataset and it can be downloaded from the following link
@@ -385,7 +211,5 @@ the accuracy of the results.
References
----------
- Background Models Challenge (BMC) website, [](http://bmc.univ-bpclermont.fr/)
- Antoine Vacavant, Thierry Chateau, Alexis Wilhelm and Laurent Lequievre. A Benchmark Dataset for
Foreground/Background Extraction. In ACCV 2012, Workshop: Background Models Challenge, LNCS
7728, 291-300. November 2012, Daejeon, Korea.
- [Background Models Challenge (BMC) website](http://bmc.univ-bpclermont.fr/)
- A Benchmark Dataset for Foreground/Background Extraction @cite vacavant2013benchmark