Skip to content

Commit 84cbffc

Browse files
committed
added tutorials for KCF tracker
1 parent 4f860dc commit 84cbffc

6 files changed

+511
-0
lines changed
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
#include <opencv2/core/utility.hpp>
2+
#include <opencv2/tracking.hpp>
3+
#include <opencv2/videoio.hpp>
4+
#include <opencv2/highgui.hpp>
5+
#include <iostream>
6+
#include <cstring>
7+
8+
using namespace std;
9+
using namespace cv;
10+
11+
// prototype of the functino for feature extractor
12+
void sobelExtractor(const Mat img, const Rect roi, Mat& feat);
13+
14+
int main( int argc, char** argv ){
15+
// show help
16+
if(argc<2){
17+
cout<<
18+
" Usage: tracker <video_name>\n"
19+
" examples:\n"
20+
" example_tracking_kcf Bolt/img/%04d.jpg\n"
21+
" example_tracking_kcf faceocc2.webm\n"
22+
<< endl;
23+
return 0;
24+
}
25+
26+
// declares all required variables
27+
Rect2d roi;
28+
Mat frame;
29+
30+
//! [param]
31+
TrackerKCF::Params param;
32+
param.desc_pca = TrackerKCF::GRAY | TrackerKCF::CN;
33+
param.desc_npca = 0;
34+
param.compress_feature = true;
35+
param.compressed_size = 2;
36+
//! [param]
37+
38+
// create a tracker object
39+
//! [create]
40+
Ptr<TrackerKCF> tracker = TrackerKCF::createTracker(param);
41+
//! [create]
42+
43+
//! [setextractor]
44+
tracker->setFeatureExtractor(sobelExtractor);
45+
//! [setextractor]
46+
47+
// set input video
48+
std::string video = argv[1];
49+
VideoCapture cap(video);
50+
51+
// get bounding box
52+
cap >> frame;
53+
roi=selectROI("tracker",frame);
54+
55+
//quit if ROI was not selected
56+
if(roi.width==0 || roi.height==0)
57+
return 0;
58+
59+
// initialize the tracker
60+
tracker->init(frame,roi);
61+
62+
// perform the tracking process
63+
printf("Start the tracking process, press ESC to quit.\n");
64+
for ( ;; ){
65+
// get frame from the video
66+
cap >> frame;
67+
68+
// stop the program if no more images
69+
if(frame.rows==0 || frame.cols==0)
70+
break;
71+
72+
// update the tracking result
73+
tracker->update(frame,roi);
74+
75+
// draw the tracked object
76+
rectangle( frame, roi, Scalar( 255, 0, 0 ), 2, 1 );
77+
78+
// show image with the tracked object
79+
imshow("tracker",frame);
80+
81+
//quit on ESC button
82+
if(waitKey(1)==27)break;
83+
}
84+
85+
return 0;
86+
}
87+
88+
void sobelExtractor(const Mat img, const Rect roi, Mat& feat){
89+
Mat sobel[2];
90+
Mat patch;
91+
Rect region=roi;
92+
93+
//! [insideimage]
94+
// extract patch inside the image
95+
if(roi.x<0){region.x=0;region.width+=roi.x;}
96+
if(roi.y<0){region.y=0;region.height+=roi.y;}
97+
if(roi.x+roi.width>img.cols)region.width=img.cols-roi.x;
98+
if(roi.y+roi.height>img.rows)region.height=img.rows-roi.y;
99+
if(region.width>img.cols)region.width=img.cols;
100+
if(region.height>img.rows)region.height=img.rows;
101+
//! [insideimage]
102+
103+
patch=img(region).clone();
104+
cvtColor(patch,patch, CV_BGR2GRAY);
105+
106+
//! [padding]
107+
// add some padding to compensate when the patch is outside image border
108+
int addTop,addBottom, addLeft, addRight;
109+
addTop=region.y-roi.y;
110+
addBottom=(roi.height+roi.y>img.rows?roi.height+roi.y-img.rows:0);
111+
addLeft=region.x-roi.x;
112+
addRight=(roi.width+roi.x>img.cols?roi.width+roi.x-img.cols:0);
113+
114+
copyMakeBorder(patch,patch,addTop,addBottom,addLeft,addRight,BORDER_REPLICATE);
115+
//! [padding]
116+
117+
//! [sobel]
118+
Sobel(patch, sobel[0], CV_32F,1,0,1);
119+
Sobel(patch, sobel[1], CV_32F,0,1,1);
120+
121+
merge(sobel,2,feat);
122+
//! [sobel]
123+
124+
//! [postprocess]
125+
feat.convertTo(feat,CV_64F);
126+
feat=feat/255.0-0.5; // normalize to range -0.5 .. 0.5
127+
//! [postprocess]
128+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#include <opencv2/core/utility.hpp>
2+
#include <opencv2/tracking.hpp>
3+
#include <opencv2/videoio.hpp>
4+
#include <opencv2/highgui.hpp>
5+
#include <iostream>
6+
#include <cstring>
7+
8+
using namespace std;
9+
using namespace cv;
10+
11+
int main( int argc, char** argv ){
12+
// show help
13+
//! [help]
14+
if(argc<2){
15+
cout<<
16+
" Usage: tracker <video_name>\n"
17+
" examples:\n"
18+
" example_tracking_kcf Bolt/img/%04d.jpg\n"
19+
" example_tracking_kcf faceocc2.webm\n"
20+
<< endl;
21+
return 0;
22+
}
23+
//! [help]
24+
25+
// declares all required variables
26+
//! [vars]
27+
Rect2d roi;
28+
Mat frame;
29+
//! [vars]
30+
31+
// create a tracker object
32+
//! [create]
33+
Ptr<Tracker> tracker = Tracker::create( "KCF" );
34+
//! [create]
35+
36+
// set input video
37+
//! [setvideo]
38+
std::string video = argv[1];
39+
VideoCapture cap(video);
40+
//! [setvideo]
41+
42+
// get bounding box
43+
//! [getframe]
44+
cap >> frame;
45+
//! [getframe]
46+
//! [selectroi]
47+
roi=selectROI("tracker",frame);
48+
//! [selectroi]
49+
50+
//quit if ROI was not selected
51+
if(roi.width==0 || roi.height==0)
52+
return 0;
53+
54+
// initialize the tracker
55+
//! [init]
56+
tracker->init(frame,roi);
57+
//! [init]
58+
59+
// perform the tracking process
60+
printf("Start the tracking process, press ESC to quit.\n");
61+
for ( ;; ){
62+
// get frame from the video
63+
cap >> frame;
64+
65+
// stop the program if no more images
66+
if(frame.rows==0 || frame.cols==0)
67+
break;
68+
69+
// update the tracking result
70+
//! [update]
71+
tracker->update(frame,roi);
72+
//! [update]
73+
74+
//! [visualization]
75+
// draw the tracked object
76+
rectangle( frame, roi, Scalar( 255, 0, 0 ), 2, 1 );
77+
78+
// show image with the tracked object
79+
imshow("tracker",frame);
80+
//! [visualization]
81+
82+
//quit on ESC button
83+
if(waitKey(1)==27)break;
84+
}
85+
86+
return 0;
87+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*----------------------------------------------
2+
* Usage:
3+
* example_tracking_multitracker <video_name> [algorithm]
4+
*
5+
* example:
6+
* example_tracking_multitracker Bolt/img/%04d.jpg
7+
* example_tracking_multitracker faceocc2.webm KCF
8+
*--------------------------------------------------*/
9+
10+
#include <opencv2/core/utility.hpp>
11+
#include <opencv2/tracking.hpp>
12+
#include <opencv2/videoio.hpp>
13+
#include <opencv2/highgui.hpp>
14+
#include <iostream>
15+
#include <cstring>
16+
#include <ctime>
17+
18+
using namespace std;
19+
using namespace cv;
20+
21+
int main( int argc, char** argv ){
22+
// show help
23+
if(argc<2){
24+
cout<<
25+
" Usage: example_tracking_multitracker <video_name> [algorithm]\n"
26+
" examples:\n"
27+
" example_tracking_multitracker Bolt/img/%04d.jpg\n"
28+
" example_tracking_multitracker faceocc2.webm MEDIANFLOW\n"
29+
<< endl;
30+
return 0;
31+
}
32+
33+
// set the default tracking algorithm
34+
std::string trackingAlg = "KCF";
35+
36+
// set the tracking algorithm from parameter
37+
if(argc>2)
38+
trackingAlg = argv[2];
39+
40+
// create the tracker
41+
//! [create]
42+
MultiTracker trackers(trackingAlg);
43+
//! [create]
44+
45+
// container of the tracked objects
46+
//! [roi]
47+
vector<Rect2d> objects;
48+
//! [roi]
49+
50+
// set input video
51+
std::string video = argv[1];
52+
VideoCapture cap(video);
53+
54+
Mat frame;
55+
56+
// get bounding box
57+
cap >> frame;
58+
//! [selectmulti]
59+
selectROI("tracker",frame,objects);
60+
//! [selectmulti]
61+
62+
//quit when the tracked object(s) is not provided
63+
if(objects.size()<1)
64+
return 0;
65+
66+
// initialize the tracker
67+
//! [init]
68+
trackers.add(frame,objects);
69+
//! [init]
70+
71+
// do the tracking
72+
printf("Start the tracking process, press ESC to quit.\n");
73+
for ( ;; ){
74+
// get frame from the video
75+
cap >> frame;
76+
77+
// stop the program if no more images
78+
if(frame.rows==0 || frame.cols==0)
79+
break;
80+
81+
//update the tracking result
82+
//! [update]
83+
trackers.update(frame);
84+
//! [update]
85+
86+
//! [result]
87+
// draw the tracked object
88+
for(unsigned i=0;i<trackers.objects.size();i++)
89+
rectangle( frame, trackers.objects[i], Scalar( 255, 0, 0 ), 2, 1 );
90+
//! [result]
91+
92+
// show image with the tracked object
93+
imshow("tracker",frame);
94+
95+
//quit on ESC button
96+
if(waitKey(1)==27)break;
97+
}
98+
99+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
Customizing the CN Tracker {#tutorial_customizing_cn_tracker}
2+
======================
3+
4+
Goal
5+
----
6+
7+
In this tutorial you will learn how to
8+
9+
- Set custom parameters for CN tracker.
10+
- Use your own feature-extractor function for the CN tracker.
11+
12+
This document contains tutorial for the @ref cv::TrackerKCF.
13+
14+
Source Code
15+
-----------
16+
17+
@includelineno tracking/samples/tutorial_customizing_cn_tracker.cpp
18+
19+
Explanation
20+
-----------
21+
22+
This part explains how to set custom parameters and use your own feature-extractor function for the CN tracker.
23+
If you need a more detailed information to use @ref cv::Tracker, please refer to @ref tutorial_introduction_to_tracker.
24+
25+
-# **Set Custom Parameters**
26+
27+
@snippet tracking/samples/tutorial_customizing_cn_tracker.cpp param
28+
29+
To set custom paramters, an object should be created. Each tracker algorithm has their own parameter format.
30+
So, in this case we should use parameter from @ref cv::TrackerKCF since we are interested in modifying the parameter of this tracker algorithm.
31+
32+
There are several parameters that can be configured as explained in @ref cv::TrackerKCF::Params.
33+
For this tutorial, we focussed on the feature extractor functions.
34+
35+
Several feature types can be used in @ref cv::TrackerKCF.
36+
In this case, the grayscale value (1 dimension) and color-names features (10 dimension),
37+
will be merged as 11 dimension feature and then compressed into 2 dimension as specified in the code.
38+
39+
If you want to use another type of pre-defined feature-extractor function, you can check in @ref cv::TrackerKCF::MODE.
40+
We will leave the non-compressed feature as 0 since we want to use a customized function.
41+
42+
-# **Using a custom function**
43+
44+
You can define your own feature-extractor function for the CN tracker.
45+
However, you need to take care about several things:
46+
- The extracted feature should have the same size as the size of the given bounding box (width and height).
47+
For the number of channels you can check the limitation in @ref cv::Mat.
48+
- You can only use features that can be compared using Euclidean distance.
49+
Features like local binary pattern (LBP) may not be suitable since it should be compared using Hamming distance.
50+
51+
Since the size of the extracted feature should be in the same size with the given bounding box,
52+
we need to take care whenever the given bounding box is partially out of range.
53+
In this case, we can copy part of image contained in the bounding box as shown in the snippet below.
54+
55+
@snippet tracking/samples/tutorial_customizing_cn_tracker.cpp insideimage
56+
57+
Whenever the copied image is smaller than the given bounding box,
58+
padding should be given to the sides where the bounding box is partially out of frame.
59+
60+
@snippet tracking/samples/tutorial_customizing_cn_tracker.cpp padding
61+
62+
-# **Defining the feature**
63+
64+
In this tutorial, the extracted feature is reponse of the Sobel filter in x and y direction.
65+
Those Sobel filter responses are concatenated, resulting a feature with 2 channels.
66+
67+
@snippet tracking/samples/tutorial_customizing_cn_tracker.cpp sobel
68+
69+
-# **Post processing**
70+
71+
Make sure to convert the feature into @ref cv::CV_64F data format and normalize its value with range -0.5 to 0.5
72+
73+
@snippet tracking/samples/tutorial_customizing_cn_tracker.cpp postprocess

0 commit comments

Comments
 (0)