mirror of
https://github.com/opencv/opencv_contrib.git
synced 2025-10-19 19:44:14 +08:00

* 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
171 lines
4.8 KiB
C++
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;
|
|
}
|