|
|
|
@ -13,29 +13,11 @@ |
|
|
|
|
#include <opencv2/highgui.hpp> |
|
|
|
|
#include <iostream> |
|
|
|
|
#include <cstring> |
|
|
|
|
#include "samples_utility.hpp" |
|
|
|
|
|
|
|
|
|
using namespace std; |
|
|
|
|
using namespace cv; |
|
|
|
|
|
|
|
|
|
class BoxExtractor { |
|
|
|
|
public: |
|
|
|
|
Rect2d extract(Mat img); |
|
|
|
|
Rect2d extract(const std::string& windowName, Mat img, bool showCrossair = true); |
|
|
|
|
|
|
|
|
|
struct handlerT{ |
|
|
|
|
bool isDrawing; |
|
|
|
|
Rect2d box; |
|
|
|
|
Mat image; |
|
|
|
|
|
|
|
|
|
// initializer list
|
|
|
|
|
handlerT(): isDrawing(false) {}; |
|
|
|
|
}params; |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
static void mouseHandler(int event, int x, int y, int flags, void *param); |
|
|
|
|
void opencv_mouse_callback( int event, int x, int y, int , void *param ); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
int main( int argc, char** argv ){ |
|
|
|
|
// show help
|
|
|
|
|
if(argc<2){ |
|
|
|
@ -48,9 +30,6 @@ int main( int argc, char** argv ){ |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// ROI selector
|
|
|
|
|
BoxExtractor box; |
|
|
|
|
|
|
|
|
|
// create the tracker
|
|
|
|
|
Ptr<Tracker> tracker = TrackerKCF::create(); |
|
|
|
|
|
|
|
|
@ -62,7 +41,7 @@ int main( int argc, char** argv ){ |
|
|
|
|
|
|
|
|
|
// get bounding box
|
|
|
|
|
cap >> frame; |
|
|
|
|
Rect2d roi=box.extract("tracker",frame); |
|
|
|
|
Rect2d roi= selectROI("tracker", frame, true, false); |
|
|
|
|
|
|
|
|
|
//quit if ROI was not selected
|
|
|
|
|
if(roi.width==0 || roi.height==0) |
|
|
|
@ -82,7 +61,13 @@ int main( int argc, char** argv ){ |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
// update the tracking result
|
|
|
|
|
tracker->update(frame,roi); |
|
|
|
|
bool isfound = tracker->update(frame,roi); |
|
|
|
|
if(!isfound) |
|
|
|
|
{ |
|
|
|
|
cout << "The target has been lost...\n"; |
|
|
|
|
waitKey(0); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// draw the tracked object
|
|
|
|
|
rectangle( frame, roi, Scalar( 255, 0, 0 ), 2, 1 ); |
|
|
|
@ -95,100 +80,3 @@ int main( int argc, char** argv ){ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void BoxExtractor::mouseHandler(int event, int x, int y, int flags, void *param){ |
|
|
|
|
BoxExtractor *self =static_cast<BoxExtractor*>(param); |
|
|
|
|
self->opencv_mouse_callback(event,x,y,flags,param); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void BoxExtractor::opencv_mouse_callback( int event, int x, int y, int , void *param ){ |
|
|
|
|
handlerT * data = (handlerT*)param; |
|
|
|
|
switch( event ){ |
|
|
|
|
// update the selected bounding box
|
|
|
|
|
case EVENT_MOUSEMOVE: |
|
|
|
|
if( data->isDrawing ){ |
|
|
|
|
data->box.width = x-data->box.x; |
|
|
|
|
data->box.height = y-data->box.y; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
// start to select the bounding box
|
|
|
|
|
case EVENT_LBUTTONDOWN: |
|
|
|
|
data->isDrawing = true; |
|
|
|
|
data->box = cvRect( x, y, 0, 0 ); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
// cleaning up the selected bounding box
|
|
|
|
|
case EVENT_LBUTTONUP: |
|
|
|
|
data->isDrawing = false; |
|
|
|
|
if( data->box.width < 0 ){ |
|
|
|
|
data->box.x += data->box.width; |
|
|
|
|
data->box.width *= -1; |
|
|
|
|
} |
|
|
|
|
if( data->box.height < 0 ){ |
|
|
|
|
data->box.y += data->box.height; |
|
|
|
|
data->box.height *= -1; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Rect2d BoxExtractor::extract(Mat img){ |
|
|
|
|
return extract("Bounding Box Extractor", img); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Rect2d BoxExtractor::extract(const std::string& windowName, Mat img, bool showCrossair){ |
|
|
|
|
|
|
|
|
|
int key=0; |
|
|
|
|
|
|
|
|
|
// show the image and give feedback to user
|
|
|
|
|
imshow(windowName,img); |
|
|
|
|
printf("Select an object to track and then press SPACE/BACKSPACE/ENTER button!\n"); |
|
|
|
|
|
|
|
|
|
// copy the data, rectangle should be drawn in the fresh image
|
|
|
|
|
params.image=img.clone(); |
|
|
|
|
|
|
|
|
|
// select the object
|
|
|
|
|
setMouseCallback( windowName, mouseHandler, (void *)¶ms ); |
|
|
|
|
|
|
|
|
|
// end selection process on SPACE (32) BACKSPACE (27) or ENTER (13)
|
|
|
|
|
while(!(key==32 || key==27 || key==13)){ |
|
|
|
|
// draw the selected object
|
|
|
|
|
rectangle( |
|
|
|
|
params.image, |
|
|
|
|
params.box, |
|
|
|
|
Scalar(255,0,0),2,1 |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
// draw cross air in the middle of bounding box
|
|
|
|
|
if(showCrossair){ |
|
|
|
|
// horizontal line
|
|
|
|
|
line( |
|
|
|
|
params.image, |
|
|
|
|
Point((int)params.box.x,(int)(params.box.y+params.box.height/2)), |
|
|
|
|
Point((int)(params.box.x+params.box.width),(int)(params.box.y+params.box.height/2)), |
|
|
|
|
Scalar(255,0,0),2,1 |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
// vertical line
|
|
|
|
|
line( |
|
|
|
|
params.image, |
|
|
|
|
Point((int)(params.box.x+params.box.width/2),(int)params.box.y), |
|
|
|
|
Point((int)(params.box.x+params.box.width/2),(int)(params.box.y+params.box.height)), |
|
|
|
|
Scalar(255,0,0),2,1 |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// show the image bouding box
|
|
|
|
|
imshow(windowName,params.image); |
|
|
|
|
|
|
|
|
|
// reset the image
|
|
|
|
|
params.image=img.clone(); |
|
|
|
|
|
|
|
|
|
//get keyboard event
|
|
|
|
|
key=waitKey(1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return params.box; |
|
|
|
|
} |
|
|
|
|