Skip to content

Commit 7c4aead

Browse files
author
Kirill Kornyakov
committed
Merge pull request #4 from lenlen/test_perftest
Added perf_test and test based on distance and overlap for tracking API
2 parents ea6fd75 + b5844af commit 7c4aead

File tree

10 files changed

+1716
-181
lines changed

10 files changed

+1716
-181
lines changed
Lines changed: 273 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,273 @@
1+
/*M///////////////////////////////////////////////////////////////////////////////////////
2+
//
3+
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4+
//
5+
// By downloading, copying, installing or using the software you agree to this license.
6+
// If you do not agree to this license, do not download, install,
7+
// copy or use the software.
8+
//
9+
//
10+
// License Agreement
11+
// For Open Source Computer Vision Library
12+
//
13+
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
14+
// Third party copyrights are property of their respective owners.
15+
//
16+
// Redistribution and use in source and binary forms, with or without modification,
17+
// are permitted provided that the following conditions are met:
18+
//
19+
// * Redistribution's of source code must retain the above copyright notice,
20+
// this list of conditions and the following disclaimer.
21+
//
22+
// * Redistribution's in binary form must reproduce the above copyright notice,
23+
// this list of conditions and the following disclaimer in the documentation
24+
// and/or other materials provided with the distribution.
25+
//
26+
// * The name of the copyright holders may not be used to endorse or promote products
27+
// derived from this software without specific prior written permission.
28+
//
29+
// This software is provided by the copyright holders and contributors "as is" and
30+
// any express or implied warranties, including, but not limited to, the implied
31+
// warranties of merchantability and fitness for a particular purpose are disclaimed.
32+
// In no event shall the Intel Corporation or contributors be liable for any direct,
33+
// indirect, incidental, special, exemplary, or consequential damages
34+
// (including, but not limited to, procurement of substitute goods or services;
35+
// loss of use, data, or profits; or business interruption) however caused
36+
// and on any theory of liability, whether in contract, strict liability,
37+
// or tort (including negligence or otherwise) arising in any way out of
38+
// the use of this software, even if advised of the possibility of such damage.
39+
//
40+
//M*/
41+
42+
#include "perf_precomp.hpp"
43+
#include <fstream>
44+
45+
using namespace std;
46+
using namespace cv;
47+
using namespace perf;
48+
using std::tr1::make_tuple;
49+
using std::tr1::get;
50+
51+
//write sanity: ./bin/opencv_perf_tracking --perf_write_sanity=true --perf_min_samples=1
52+
//verify sanity: ./bin/opencv_perf_tracking --perf_min_samples=1
53+
54+
#define TESTSET_NAMES testing::Values("david","dudek","faceocc2")
55+
//#define TESTSET_NAMES testing::internal::ValueArray1<string>("david")
56+
#define SEGMENTS testing::Values(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
57+
58+
const string TRACKING_DIR = "cv/tracking";
59+
const string FOLDER_IMG = "data";
60+
61+
typedef perf::TestBaseWithParam<tr1::tuple<string, int> > tracking;
62+
63+
std::vector<std::string> splitString( std::string s, std::string delimiter )
64+
{
65+
std::vector<string> token;
66+
size_t pos = 0;
67+
while ( ( pos = s.find( delimiter ) ) != std::string::npos )
68+
{
69+
token.push_back( s.substr( 0, pos ) );
70+
s.erase( 0, pos + delimiter.length() );
71+
}
72+
token.push_back( s );
73+
return token;
74+
}
75+
76+
void checkData( const string& datasetMeta, int& startFrame, string& prefix, string& suffix )
77+
{
78+
//get informations on the current test data
79+
FileStorage fs;
80+
fs.open( datasetMeta, FileStorage::READ );
81+
fs["start"] >> startFrame;
82+
fs["prefix"] >> prefix;
83+
fs["suffix"] >> suffix;
84+
fs.release();
85+
}
86+
87+
bool getGroundTruth( const string& gtFile, vector<Rect>& gtBBs )
88+
{
89+
ifstream gt;
90+
//open the ground truth
91+
gt.open( gtFile.c_str() );
92+
if( !gt.is_open() )
93+
{
94+
return false;
95+
}
96+
string line;
97+
Rect currentBB;
98+
while ( getline( gt, line ) )
99+
{
100+
vector<string> tokens = splitString( line, "," );
101+
102+
if( tokens.size() != 4 )
103+
{
104+
return false;
105+
}
106+
107+
gtBBs.push_back(
108+
Rect( atoi( tokens.at( 0 ).c_str() ), atoi( tokens.at( 1 ).c_str() ), atoi( tokens.at( 2 ).c_str() ), atoi( tokens.at( 3 ).c_str() ) ) );
109+
}
110+
return true;
111+
}
112+
113+
void getSegment( int segmentId, int numSegments, int bbCounter, int& startFrame, int& endFrame )
114+
{
115+
//compute the start and the and for each segment
116+
int gtStartFrame = startFrame;
117+
int numFrame = bbCounter / numSegments;
118+
startFrame += ( segmentId - 1 ) * numFrame;
119+
endFrame = startFrame + numFrame;
120+
121+
if( ( segmentId ) == numSegments )
122+
endFrame = bbCounter + gtStartFrame - 1;
123+
}
124+
125+
void getMatOfRects( const vector<Rect>& bbs, Mat& bbs_mat )
126+
{
127+
for ( size_t b = 0; b < bbs.size(); b++ )
128+
{
129+
bbs_mat.at<float>( b, 0 ) = bbs[b].x;
130+
bbs_mat.at<float>( b, 1 ) = bbs[b].y;
131+
bbs_mat.at<float>( b, 2 ) = bbs[b].width;
132+
bbs_mat.at<float>( b, 3 ) = bbs[b].height;
133+
}
134+
}
135+
136+
PERF_TEST_P(tracking, mil, testing::Combine(TESTSET_NAMES, SEGMENTS))
137+
{
138+
string video = get<0>( GetParam() );
139+
int segmentId = get<1>( GetParam() );
140+
141+
int startFrame;
142+
string prefix;
143+
string suffix;
144+
string datasetMeta = getDataPath( TRACKING_DIR + "/" + video + "/" + video + ".yml" );
145+
checkData( datasetMeta, startFrame, prefix, suffix );
146+
int gtStartFrame = startFrame;
147+
148+
vector<Rect> gtBBs;
149+
string gtFile = getDataPath( TRACKING_DIR + "/" + video + "/gt.txt" );
150+
if( !getGroundTruth( gtFile, gtBBs ) )
151+
FAIL()<< "Ground truth file " << gtFile << " can not be read" << endl;
152+
int bbCounter = gtBBs.size();
153+
154+
Mat frame;
155+
bool initialized = false;
156+
vector<Rect> bbs;
157+
158+
Ptr<Tracker> tracker = Tracker::create( "MIL" );
159+
string folder = TRACKING_DIR + "/" + video + "/" + FOLDER_IMG;
160+
int numSegments = ( sizeof ( SEGMENTS)/sizeof(int) );
161+
int endFrame = 0;
162+
getSegment( segmentId, numSegments, bbCounter, startFrame, endFrame );
163+
164+
Rect currentBB = gtBBs[startFrame - gtStartFrame];
165+
166+
TEST_CYCLE_N(1)
167+
{
168+
VideoCapture c;
169+
c.open( getDataPath( TRACKING_DIR + "/" + video + "/" + FOLDER_IMG + "/" + video + ".webm" ) );
170+
c.set( CAP_PROP_POS_FRAMES, startFrame );
171+
172+
for ( int frameCounter = startFrame; frameCounter < endFrame; frameCounter++ )
173+
{
174+
c >> frame;
175+
176+
if( frame.empty() )
177+
{
178+
break;
179+
}
180+
181+
if( !initialized )
182+
{
183+
if( !tracker->init( frame, currentBB ) )
184+
{
185+
FAIL()<< "Could not initialize tracker" << endl;
186+
return;
187+
}
188+
initialized = true;
189+
}
190+
else if( initialized )
191+
{
192+
tracker->update( frame, currentBB );
193+
}
194+
bbs.push_back( currentBB );
195+
196+
}
197+
}
198+
//save the bounding boxes in a Mat
199+
Mat bbs_mat( bbs.size(), 4, CV_32F );
200+
getMatOfRects( bbs, bbs_mat );
201+
202+
SANITY_CHECK( bbs_mat, 15, ERROR_RELATIVE );
203+
204+
}
205+
206+
PERF_TEST_P(tracking, boosting, testing::Combine(TESTSET_NAMES, SEGMENTS))
207+
{
208+
string video = get<0>( GetParam() );
209+
int segmentId = get<1>( GetParam() );
210+
211+
int startFrame;
212+
string prefix;
213+
string suffix;
214+
string datasetMeta = getDataPath( TRACKING_DIR + "/" + video + "/" + video + ".yml" );
215+
checkData( datasetMeta, startFrame, prefix, suffix );
216+
int gtStartFrame = startFrame;
217+
218+
vector<Rect> gtBBs;
219+
string gtFile = getDataPath( TRACKING_DIR + "/" + video + "/gt.txt" );
220+
if( !getGroundTruth( gtFile, gtBBs ) )
221+
FAIL()<< "Ground truth file " << gtFile << " can not be read" << endl;
222+
int bbCounter = gtBBs.size();
223+
224+
Mat frame;
225+
bool initialized = false;
226+
vector<Rect> bbs;
227+
228+
Ptr<Tracker> tracker = Tracker::create( "BOOSTING" );
229+
string folder = TRACKING_DIR + "/" + video + "/" + FOLDER_IMG;
230+
int numSegments = ( sizeof ( SEGMENTS)/sizeof(int) );
231+
int endFrame = 0;
232+
getSegment( segmentId, numSegments, bbCounter, startFrame, endFrame );
233+
234+
Rect currentBB = gtBBs[startFrame - gtStartFrame];
235+
236+
TEST_CYCLE_N(1)
237+
{
238+
VideoCapture c;
239+
c.open( getDataPath( TRACKING_DIR + "/" + video + "/" + FOLDER_IMG + "/" + video + ".webm" ) );
240+
c.set( CAP_PROP_POS_FRAMES, startFrame );
241+
for ( int frameCounter = startFrame; frameCounter < endFrame; frameCounter++ )
242+
{
243+
c >> frame;
244+
245+
if( frame.empty() )
246+
{
247+
break;
248+
}
249+
250+
if( !initialized )
251+
{
252+
if( !tracker->init( frame, currentBB ) )
253+
{
254+
FAIL()<< "Could not initialize tracker" << endl;
255+
return;
256+
}
257+
initialized = true;
258+
}
259+
else if( initialized )
260+
{
261+
tracker->update( frame, currentBB );
262+
}
263+
bbs.push_back( currentBB );
264+
265+
}
266+
}
267+
//save the bounding boxes in a Mat
268+
Mat bbs_mat( bbs.size(), 4, CV_32F );
269+
getMatOfRects( bbs, bbs_mat );
270+
271+
SANITY_CHECK( bbs_mat, 15, ERROR_RELATIVE );
272+
273+
}

modules/tracking/perf/perf_tracking.cpp

Lines changed: 0 additions & 46 deletions
This file was deleted.

modules/tracking/samples/tracker.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,17 @@ static bool selectObject = false;
1313
static bool startSelection = false;
1414

1515
static const char* keys =
16-
{ "{@tracker_algorithm | | tracker algorithm }"
17-
"{@video_name | | video name }" };
16+
{ "{@tracker_algorithm | | Tracker algorithm }"
17+
"{@video_name | | video name }"
18+
"{@start_frame |1| Start frame }" };
1819

1920
static void help()
2021
{
2122
cout << "\nThis example shows the functionality of \"Long-term optical tracking API\""
2223
"-- pause video [p] and draw a bounding box around the target to start the tracker\n"
24+
"Example of <video_name> is in opencv_extra/testdata/cv/tracking/\n"
2325
"Call:\n"
24-
"./tracker <tracker_algorithm> <video_name>\n"
26+
"./tracker <tracker_algorithm> <video_name> <start_frame>\n"
2527
<< endl;
2628

2729
cout << "\n\nHot keys: \n"
@@ -69,6 +71,7 @@ int main( int argc, char** argv )
6971

7072
String tracker_algorithm = parser.get<String>( 0 );
7173
String video_name = parser.get<String>( 1 );
74+
int start_frame = parser.get<int>( 2 );
7275

7376
if( tracker_algorithm.empty() || video_name.empty() )
7477
{
@@ -79,6 +82,7 @@ int main( int argc, char** argv )
7982
//open the capture
8083
VideoCapture cap;
8184
cap.open( video_name );
85+
cap.set( CAP_PROP_POS_FRAMES, start_frame );
8286

8387
if( !cap.isOpened() )
8488
{
@@ -108,11 +112,19 @@ int main( int argc, char** argv )
108112
imshow( "Tracking API", image );
109113

110114
bool initialized = false;
115+
int frameCounter = 0;
116+
111117
for ( ;; )
112118
{
113119
if( !paused )
114120
{
115121
cap >> frame;
122+
123+
if( frame.empty() )
124+
{
125+
break;
126+
}
127+
116128
frame.copyTo( image );
117129

118130
if( !initialized && selectObject )
@@ -134,6 +146,7 @@ int main( int argc, char** argv )
134146
}
135147
}
136148
imshow( "Tracking API", image );
149+
frameCounter++;
137150
}
138151

139152
char c = (char) waitKey( 2 );

0 commit comments

Comments
 (0)