Commit 84cbffc7 authored by Kurnianggoro's avatar Kurnianggoro

added tutorials for KCF tracker

parent 4f860dcf
#include <opencv2/core/utility.hpp>
#include <opencv2/tracking.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <cstring>
using namespace std;
using namespace cv;
// prototype of the functino for feature extractor
void sobelExtractor(const Mat img, const Rect roi, Mat& feat);
int main( int argc, char** argv ){
// show help
if(argc<2){
cout<<
" Usage: tracker <video_name>\n"
" examples:\n"
" example_tracking_kcf Bolt/img/%04d.jpg\n"
" example_tracking_kcf faceocc2.webm\n"
<< endl;
return 0;
}
// declares all required variables
Rect2d roi;
Mat frame;
//! [param]
TrackerKCF::Params param;
param.desc_pca = TrackerKCF::GRAY | TrackerKCF::CN;
param.desc_npca = 0;
param.compress_feature = true;
param.compressed_size = 2;
//! [param]
// create a tracker object
//! [create]
Ptr<TrackerKCF> tracker = TrackerKCF::createTracker(param);
//! [create]
//! [setextractor]
tracker->setFeatureExtractor(sobelExtractor);
//! [setextractor]
// set input video
std::string video = argv[1];
VideoCapture cap(video);
// get bounding box
cap >> frame;
roi=selectROI("tracker",frame);
//quit if ROI was not selected
if(roi.width==0 || roi.height==0)
return 0;
// initialize the tracker
tracker->init(frame,roi);
// perform the tracking process
printf("Start the tracking process, press ESC to quit.\n");
for ( ;; ){
// get frame from the video
cap >> frame;
// stop the program if no more images
if(frame.rows==0 || frame.cols==0)
break;
// update the tracking result
tracker->update(frame,roi);
// draw the tracked object
rectangle( frame, roi, Scalar( 255, 0, 0 ), 2, 1 );
// show image with the tracked object
imshow("tracker",frame);
//quit on ESC button
if(waitKey(1)==27)break;
}
return 0;
}
void sobelExtractor(const Mat img, const Rect roi, Mat& feat){
Mat sobel[2];
Mat patch;
Rect region=roi;
//! [insideimage]
// extract patch inside the image
if(roi.x<0){region.x=0;region.width+=roi.x;}
if(roi.y<0){region.y=0;region.height+=roi.y;}
if(roi.x+roi.width>img.cols)region.width=img.cols-roi.x;
if(roi.y+roi.height>img.rows)region.height=img.rows-roi.y;
if(region.width>img.cols)region.width=img.cols;
if(region.height>img.rows)region.height=img.rows;
//! [insideimage]
patch=img(region).clone();
cvtColor(patch,patch, CV_BGR2GRAY);
//! [padding]
// add some padding to compensate when the patch is outside image border
int addTop,addBottom, addLeft, addRight;
addTop=region.y-roi.y;
addBottom=(roi.height+roi.y>img.rows?roi.height+roi.y-img.rows:0);
addLeft=region.x-roi.x;
addRight=(roi.width+roi.x>img.cols?roi.width+roi.x-img.cols:0);
copyMakeBorder(patch,patch,addTop,addBottom,addLeft,addRight,BORDER_REPLICATE);
//! [padding]
//! [sobel]
Sobel(patch, sobel[0], CV_32F,1,0,1);
Sobel(patch, sobel[1], CV_32F,0,1,1);
merge(sobel,2,feat);
//! [sobel]
//! [postprocess]
feat.convertTo(feat,CV_64F);
feat=feat/255.0-0.5; // normalize to range -0.5 .. 0.5
//! [postprocess]
}
#include <opencv2/core/utility.hpp>
#include <opencv2/tracking.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <cstring>
using namespace std;
using namespace cv;
int main( int argc, char** argv ){
// show help
//! [help]
if(argc<2){
cout<<
" Usage: tracker <video_name>\n"
" examples:\n"
" example_tracking_kcf Bolt/img/%04d.jpg\n"
" example_tracking_kcf faceocc2.webm\n"
<< endl;
return 0;
}
//! [help]
// declares all required variables
//! [vars]
Rect2d roi;
Mat frame;
//! [vars]
// create a tracker object
//! [create]
Ptr<Tracker> tracker = Tracker::create( "KCF" );
//! [create]
// set input video
//! [setvideo]
std::string video = argv[1];
VideoCapture cap(video);
//! [setvideo]
// get bounding box
//! [getframe]
cap >> frame;
//! [getframe]
//! [selectroi]
roi=selectROI("tracker",frame);
//! [selectroi]
//quit if ROI was not selected
if(roi.width==0 || roi.height==0)
return 0;
// initialize the tracker
//! [init]
tracker->init(frame,roi);
//! [init]
// perform the tracking process
printf("Start the tracking process, press ESC to quit.\n");
for ( ;; ){
// get frame from the video
cap >> frame;
// stop the program if no more images
if(frame.rows==0 || frame.cols==0)
break;
// update the tracking result
//! [update]
tracker->update(frame,roi);
//! [update]
//! [visualization]
// draw the tracked object
rectangle( frame, roi, Scalar( 255, 0, 0 ), 2, 1 );
// show image with the tracked object
imshow("tracker",frame);
//! [visualization]
//quit on ESC button
if(waitKey(1)==27)break;
}
return 0;
}
/*----------------------------------------------
* Usage:
* example_tracking_multitracker <video_name> [algorithm]
*
* example:
* example_tracking_multitracker Bolt/img/%04d.jpg
* example_tracking_multitracker faceocc2.webm KCF
*--------------------------------------------------*/
#include <opencv2/core/utility.hpp>
#include <opencv2/tracking.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <cstring>
#include <ctime>
using namespace std;
using namespace cv;
int main( int argc, char** argv ){
// show help
if(argc<2){
cout<<
" Usage: example_tracking_multitracker <video_name> [algorithm]\n"
" examples:\n"
" example_tracking_multitracker Bolt/img/%04d.jpg\n"
" example_tracking_multitracker faceocc2.webm MEDIANFLOW\n"
<< endl;
return 0;
}
// set the default tracking algorithm
std::string trackingAlg = "KCF";
// set the tracking algorithm from parameter
if(argc>2)
trackingAlg = argv[2];
// create the tracker
//! [create]
MultiTracker trackers(trackingAlg);
//! [create]
// container of the tracked objects
//! [roi]
vector<Rect2d> objects;
//! [roi]
// set input video
std::string video = argv[1];
VideoCapture cap(video);
Mat frame;
// get bounding box
cap >> frame;
//! [selectmulti]
selectROI("tracker",frame,objects);
//! [selectmulti]
//quit when the tracked object(s) is not provided
if(objects.size()<1)
return 0;
// initialize the tracker
//! [init]
trackers.add(frame,objects);
//! [init]
// do the tracking
printf("Start the tracking process, press ESC to quit.\n");
for ( ;; ){
// get frame from the video
cap >> frame;
// stop the program if no more images
if(frame.rows==0 || frame.cols==0)
break;
//update the tracking result
//! [update]
trackers.update(frame);
//! [update]
//! [result]
// draw the tracked object
for(unsigned i=0;i<trackers.objects.size();i++)
rectangle( frame, trackers.objects[i], Scalar( 255, 0, 0 ), 2, 1 );
//! [result]
// show image with the tracked object
imshow("tracker",frame);
//quit on ESC button
if(waitKey(1)==27)break;
}
}
Customizing the CN Tracker {#tutorial_customizing_cn_tracker}
======================
Goal
----
In this tutorial you will learn how to
- Set custom parameters for CN tracker.
- Use your own feature-extractor function for the CN tracker.
This document contains tutorial for the @ref cv::TrackerKCF.
Source Code
-----------
@includelineno tracking/samples/tutorial_customizing_cn_tracker.cpp
Explanation
-----------
This part explains how to set custom parameters and use your own feature-extractor function for the CN tracker.
If you need a more detailed information to use @ref cv::Tracker, please refer to @ref tutorial_introduction_to_tracker.
-# **Set Custom Parameters**
@snippet tracking/samples/tutorial_customizing_cn_tracker.cpp param
To set custom paramters, an object should be created. Each tracker algorithm has their own parameter format.
So, in this case we should use parameter from @ref cv::TrackerKCF since we are interested in modifying the parameter of this tracker algorithm.
There are several parameters that can be configured as explained in @ref cv::TrackerKCF::Params.
For this tutorial, we focussed on the feature extractor functions.
Several feature types can be used in @ref cv::TrackerKCF.
In this case, the grayscale value (1 dimension) and color-names features (10 dimension),
will be merged as 11 dimension feature and then compressed into 2 dimension as specified in the code.
If you want to use another type of pre-defined feature-extractor function, you can check in @ref cv::TrackerKCF::MODE.
We will leave the non-compressed feature as 0 since we want to use a customized function.
-# **Using a custom function**
You can define your own feature-extractor function for the CN tracker.
However, you need to take care about several things:
- The extracted feature should have the same size as the size of the given bounding box (width and height).
For the number of channels you can check the limitation in @ref cv::Mat.
- You can only use features that can be compared using Euclidean distance.
Features like local binary pattern (LBP) may not be suitable since it should be compared using Hamming distance.
Since the size of the extracted feature should be in the same size with the given bounding box,
we need to take care whenever the given bounding box is partially out of range.
In this case, we can copy part of image contained in the bounding box as shown in the snippet below.
@snippet tracking/samples/tutorial_customizing_cn_tracker.cpp insideimage
Whenever the copied image is smaller than the given bounding box,
padding should be given to the sides where the bounding box is partially out of frame.
@snippet tracking/samples/tutorial_customizing_cn_tracker.cpp padding
-# **Defining the feature**
In this tutorial, the extracted feature is reponse of the Sobel filter in x and y direction.
Those Sobel filter responses are concatenated, resulting a feature with 2 channels.
@snippet tracking/samples/tutorial_customizing_cn_tracker.cpp sobel
-# **Post processing**
Make sure to convert the feature into @ref cv::CV_64F data format and normalize its value with range -0.5 to 0.5
@snippet tracking/samples/tutorial_customizing_cn_tracker.cpp postprocess
Introduction to OpenCV Tracker {#tutorial_introduction_to_tracker}
==============================
Goal
----
In this tutorial you will learn how to
- Create a tracker object.
- Use the roiSelector function to select a ROI from a given image.
- Track a specific region in a given image.
Source Code
-----------
@include tracking/samples/tutorial_introduction_to_tracker.cpp
Explanation
-----------
-# **Set up the input video**
@snippet tracking/samples/tutorial_introduction_to_tracker.cpp help
In this tutorial, you can choose between video or list of images for the program input.
As written in the help, you should specify the input video as parameter of the program.
If you want to use image list as input, the image list should have formatted numbering
as shown in help. In the help, it means that the image files are numbered with 4 digits
(e.g. the file naming will be 0001.jpg, 0002.jpg, and so on).
You can find video samples in Itseez/opencv_extra/testdata/cv/tracking
<https://github.com/Itseez/opencv_extra/tree/master/testdata/cv/tracking>
-# **Declares the required variables**
You need roi to record the bounding box of the tracked object. The value stored in this
variable will be updated using the tracker object.
@snippet tracking/samples/tutorial_introduction_to_tracker.cpp vars
The frame variable is used to hold the image data from each frame of the input video or images list.
-# **Creating a tracker object**
@snippet tracking/samples/tutorial_introduction_to_tracker.cpp create
There are at least 5 types of tracker algorithms that can be used:
+ MIL
+ BOOSTING
+ MEDIANFLOW
+ TLD
+ KCF
Each tracker algorithm has their own advantages and disadvantages, please refer the documentation of @ref cv::Tracker for more detailed information.
-# **Select the tracked object**
@snippet tracking/samples/tutorial_introduction_to_tracker.cpp selectroi
Using this function, you can select the bounding box of the tracked object using a GUI.
With default parameters, the selection is started from the center of the box and a middle cross will be shown.
See @ref cv::selectROI for more detailed information.
-# **Initializing the tracker object**
@snippet tracking/samples/tutorial_introduction_to_tracker.cpp init
Tracker algorithm should be initialized with the provided image data as well as the bounding box of the tracked object.
Make sure that the bounding box is not valid (size more than zero) to avoid the initialization process failed.
-# **Update**
@snippet tracking/samples/tutorial_introduction_to_tracker.cpp update
This update function will perform the tracking process and pass the result to the roi variable.
Using MultiTracker {#tutorial_multitracker}
==================
Goal
----
In this tutorial you will learn how to
- Create a MultiTracker object.
- Track several objects at once using the MultiTracker object.
Source Code
-----------
@includelineno tracking/samples/tutorial_multitracker.cpp
Explanation
-----------
-# **Create the MultiTracker object**
@snippet tracking/samples/tutorial_multitracker.cpp create
You can create the MultiTracker object and use the same tracking algorithm for all tracked object as shown in the snippet.
If you want to use different type of tracking algorithm for each tracked object, you should define the tracking algorithm whenever a new object is added to the MultiTracker object.
-# **Selection of multiple objects**
@snippet tracking/samples/tutorial_multitracker.cpp selectmulti
You can use @ref cv::selectROI to select multiple objects with
the result stored in a vector of @ref cv::Rect2d as shown in the code.
You can also use another kind of selection scheme, please refer to @ref cv::selectROI for detailed information.
-# **Adding the tracked object to MultiTracker**
@snippet tracking/samples/tutorial_multitracker.cpp init
You can add all tracked objects at once to the MultiTracker as shown in the code.
In this case, all objects will be tracked using same tracking algorithm as specified in decaration of MultiTracker object.
If you want to use different tracker algorithms for each tracked object,
You should add the tracked objects one by one and specify their tracking algorithm using the variant of @ref cv::MultiTracker::add.
@sa cv::MultiTracker::add( const String& trackerType, const Mat& image, const Rect2d& boundingBox )
-# **Obtaining the result**
@snippet tracking/samples/tutorial_multitracker.cpp result
You can access the result from the public variable @ref cv::MultiTracker::objects provided by the MultiTracker class as shown in the code.
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