1
0
mirror of https://github.com/opencv/opencv_contrib.git synced 2025-10-19 19:44:14 +08:00
Files
opencv_contrib/modules/tracking/samples/tracker.cpp
Vladislav Sovrasov 41995b76e8 KCF speedup (#1374)
* kcf use float data type rather than double.

In our practice, float is good enough and could get better performance.
With this patch, one of my benchmark could get about 20% performance gain.

Signed-off-by: Zhigang Gong <zhigang.gong@intel.com>

* Offload transpose matrix multiplication to ocl.

The matrix multiplication in updateProjectMatrix is one of the
hotspot. And because of the matrix shape is special, say the
m is very short but the n is very large. The GEMM implementation
in neither the clBLAS nor the in trunk implementation are very
inefficient, I implement an standalone transpose matrix mulplication
kernel here. It can get about 10% performance gain on Intel
desktop platform or 20% performance gain on a braswell platform.
And in the mean time, the CPU utilization will be lower.

Signed-off-by: Zhigang Gong <zhigang.gong@intel.com>

* Add verification code for kcf ocl transpose mm kernel.

Signed-off-by: Zhigang Gong <zhigang.gong@linux.intel.com>

* tracking: show FPS in traker sample

* tracking: fix MSVC warnings in KCF

* tracking: move OCL kernel initialization to constructor in KCF
2017-10-10 13:54:22 +03:00

171 lines
4.8 KiB
C++

#include <opencv2/core/utility.hpp>
#include <opencv2/tracking.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <cstring>
#include "samples_utility.hpp"
using namespace std;
using namespace cv;
static const char* keys =
{ "{@tracker_algorithm | | Tracker algorithm }"
"{@video_name | | video name }"
"{@start_frame |0| Start frame }"
"{@bounding_frame |0,0,0,0| Initial bounding frame}"};
static void help()
{
cout << "\nThis example shows the functionality of \"Long-term optical tracking API\""
"-- pause video [p] and draw a bounding box around the target to start the tracker\n"
"Example of <video_name> is in opencv_extra/testdata/cv/tracking/\n"
"Call:\n"
"./tracker <tracker_algorithm> <video_name> <start_frame> [<bounding_frame>]\n"
"tracker_algorithm can be: MIL, BOOSTING, MEDIANFLOW, TLD\n"
<< endl;
cout << "\n\nHot keys: \n"
"\tq - quit the program\n"
"\tp - pause video\n";
}
int main( int argc, char** argv ){
CommandLineParser parser( argc, argv, keys );
String tracker_algorithm = parser.get<String>( 0 );
String video_name = parser.get<String>( 1 );
int start_frame = parser.get<int>( 2 );
if( tracker_algorithm.empty() || video_name.empty() )
{
help();
return -1;
}
int coords[4]={0,0,0,0};
bool initBoxWasGivenInCommandLine=false;
{
String initBoundingBox=parser.get<String>(3);
for(size_t npos=0,pos=0,ctr=0;ctr<4;ctr++){
npos=initBoundingBox.find_first_of(',',pos);
if(npos==string::npos && ctr<3){
printf("bounding box should be given in format \"x1,y1,x2,y2\",where x's and y's are integer cordinates of opposed corners of bdd box\n");
printf("got: %s\n",initBoundingBox.substr(pos,string::npos).c_str());
printf("manual selection of bounding box will be employed\n");
break;
}
int num=atoi(initBoundingBox.substr(pos,(ctr==3)?(string::npos):(npos-pos)).c_str());
if(num<=0){
printf("bounding box should be given in format \"x1,y1,x2,y2\",where x's and y's are integer cordinates of opposed corners of bdd box\n");
printf("got: %s\n",initBoundingBox.substr(pos,npos-pos).c_str());
printf("manual selection of bounding box will be employed\n");
break;
}
coords[ctr]=num;
pos=npos+1;
}
if(coords[0]>0 && coords[1]>0 && coords[2]>0 && coords[3]>0){
initBoxWasGivenInCommandLine=true;
}
}
//open the capture
VideoCapture cap;
cap.open( video_name );
cap.set( CAP_PROP_POS_FRAMES, start_frame );
if( !cap.isOpened() )
{
help();
cout << "***Could not initialize capturing...***\n";
cout << "Current parameter's value: \n";
parser.printMessage();
return -1;
}
Mat frame;
namedWindow( "Tracking API", 1 );
Mat image;
Rect2d boundingBox;
bool paused = false;
//instantiates the specific Tracker
Ptr<Tracker> tracker = createTrackerByName(tracker_algorithm);
if( tracker == NULL )
{
cout << "***Error in the instantiation of the tracker...***\n";
return -1;
}
//get the first frame
cap >> frame;
frame.copyTo( image );
if(initBoxWasGivenInCommandLine){
boundingBox.x = coords[0];
boundingBox.y = coords[1];
boundingBox.width = std::abs( coords[2] - coords[0] );
boundingBox.height = std::abs( coords[3]-coords[1]);
printf("bounding box with vertices (%d,%d) and (%d,%d) was given in command line\n",coords[0],coords[1],coords[2],coords[3]);
rectangle( image, boundingBox, Scalar( 255, 0, 0 ), 2, 1 );
}
else
boundingBox = selectROI("Tracking API", image);
imshow( "Tracking API", image );
bool initialized = false;
int frameCounter = 0;
int64 timeTotal = 0;
for ( ;; )
{
if( !paused )
{
if(initialized){
cap >> frame;
if(frame.empty()){
break;
}
frame.copyTo( image );
}
if( !initialized )
{
//initializes the tracker
if( !tracker->init( frame, boundingBox ) )
{
cout << "***Could not initialize tracker...***\n";
return -1;
}
initialized = true;
}
else if( initialized )
{
int64 frameTime = getTickCount();
//updates the tracker
if( tracker->update( frame, boundingBox ) )
{
rectangle( image, boundingBox, Scalar( 255, 0, 0 ), 2, 1 );
}
frameTime = getTickCount() - frameTime;
timeTotal += frameTime;
}
imshow( "Tracking API", image );
frameCounter++;
}
char c = (char) waitKey( 2 );
if( c == 'q' )
break;
if( c == 'p' )
paused = !paused;
}
double s = frameCounter / (timeTotal / getTickFrequency());
printf("FPS: %f\n", s);
return 0;
}