Commit 194455a4 authored by Kurnianggoro's avatar Kurnianggoro

Add: roi selector

parent 0dd273fa
......@@ -237,7 +237,6 @@ MultiTracker diagram
@enduml
@startuml{multi_tracker_uml.png}
package "MultiTracker class" #DDDDDD {
class MultiTracker{
MultiTracker(const String& trackerType = "" );
......@@ -254,5 +253,4 @@ MultiTracker diagram
}
}
@enduml
......@@ -1322,6 +1322,41 @@ class CV_EXPORTS_W MultiTracker
String defaultAlgorithm;
};
class ROISelector {
public:
Rect2d select(Mat img, bool fromCenter = true);
Rect2d select(const std::string& windowName, Mat img, bool showCrossair = true, bool fromCenter = true);
void select(const std::string& windowName, Mat img, std::vector<Rect2d> & boundingBox, bool fromCenter = true);
struct handlerT{
// basic parameters
bool isDrawing;
Rect2d box;
Mat image;
// parameters for drawing from the center
bool drawFromCenter;
Point2f center;
// initializer list
handlerT(): isDrawing(false), drawFromCenter(true) {};
}selectorParams;
// to store the tracked objects
std::vector<handlerT> objects;
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 );
// save the keypressed characted
int key;
};
Rect2d CV_EXPORTS_W selectROI(Mat img, bool fromCenter = true);
Rect2d CV_EXPORTS_W selectROI(const std::string& windowName, Mat img, bool showCrossair = true, bool fromCenter = true);
void CV_EXPORTS_W selectROI(const std::string& windowName, Mat img, std::vector<Rect2d> & boundingBox, bool fromCenter = true);
} /* namespace cv */
#endif
......@@ -36,37 +36,6 @@
using namespace std;
using namespace cv;
class BoxExtractor {
public:
Rect2d selectROI(Mat img, bool fromCenter = true);
Rect2d selectROI(const std::string& windowName, Mat img, bool showCrossair = true, bool fromCenter = true);
void selectROI(const std::string& windowName, Mat img, std::vector<Rect2d> & boundingBox, bool fromCenter = true);
struct handlerT{
// basic parameters
bool isDrawing;
Rect2d box;
Mat image;
// parameters for drawing from the center
bool drawFromCenter;
Point2f center;
// initializer list
handlerT(): isDrawing(false), drawFromCenter(true) {};
}params;
// to store the tracked objects
vector<handlerT> objects;
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 );
// save the keypressed characted
int key;
};
int main( int argc, char** argv ){
// show help
if(argc<2){
......@@ -95,9 +64,6 @@ int main( int argc, char** argv ){
std::string text;
char buffer [50];
// ROI selector
BoxExtractor box;
// set the default tracking algorithm
std::string trackingAlg = "KCF";
......@@ -119,7 +85,7 @@ int main( int argc, char** argv ){
// get bounding box
cap >> frame;
box.selectROI("tracker",frame,objects);
selectROI("tracker",frame,objects);
//quit when the tracked object(s) is not provided
if(objects.size()<1)
......@@ -177,128 +143,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 ){
if(data->drawFromCenter){
data->box.width = 2*(x-data->center.x)/*data->box.x*/;
data->box.height = 2*(y-data->center.y)/*data->box.y*/;
data->box.x = data->center.x-data->box.width/2.0;
data->box.y = data->center.y-data->box.height/2.0;
}else{
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 );
data->center = Point2f((float)x,(float)y);
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::selectROI(Mat img, bool fromCenter){
return selectROI("Bounding Box Extractor", img, fromCenter);
}
Rect2d BoxExtractor::selectROI(const std::string& windowName, Mat img, bool showCrossair, bool fromCenter){
key=0;
// set the drawing mode
params.drawFromCenter = fromCenter;
// show the image and give feedback to user
imshow(windowName,img);
// copy the data, rectangle should be drawn in the fresh image
params.image=img.clone();
// select the object
setMouseCallback( windowName, mouseHandler, (void *)&params );
// 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;
}
void BoxExtractor::selectROI(const std::string& windowName, Mat img, std::vector<Rect2d> & boundingBox, bool fromCenter){
vector<Rect2d> box;
Rect2d temp;
key=0;
// show notice to user
printf(RED "Select an object to track and then press SPACE or ENTER button!\n" RESET);
printf(RED "Finish the selection process by pressing BACKSPACE button!\n" RESET);
// while key is not Backspace
while(key!=27){
temp=selectROI(windowName, img, true, fromCenter);
if(temp.width>0 && temp.height>0)
box.push_back(temp);
}
boundingBox=box;
}
\ No newline at end of file
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "precomp.hpp"
namespace cv {
void ROISelector::mouseHandler(int event, int x, int y, int flags, void *param){
ROISelector *self =static_cast<ROISelector*>(param);
self->opencv_mouse_callback(event,x,y,flags,param);
}
void ROISelector::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 ){
if(data->drawFromCenter){
data->box.width = 2*(x-data->center.x)/*data->box.x*/;
data->box.height = 2*(y-data->center.y)/*data->box.y*/;
data->box.x = data->center.x-data->box.width/2.0;
data->box.y = data->center.y-data->box.height/2.0;
}else{
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 );
data->center = Point2f((float)x,(float)y);
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 ROISelector::select(Mat img, bool fromCenter){
return select("ROI selector", img, fromCenter);
}
Rect2d ROISelector::select(const std::string& windowName, Mat img, bool showCrossair, bool fromCenter){
key=0;
// set the drawing mode
selectorParams.drawFromCenter = fromCenter;
// show the image and give feedback to user
imshow(windowName,img);
// copy the data, rectangle should be drawn in the fresh image
selectorParams.image=img.clone();
// select the object
setMouseCallback( windowName, mouseHandler, (void *)&selectorParams );
// end selection process on SPACE (32) BACKSPACE (27) or ENTER (13)
while(!(key==32 || key==27 || key==13)){
// draw the selected object
rectangle(
selectorParams.image,
selectorParams.box,
Scalar(255,0,0),2,1
);
// draw cross air in the middle of bounding box
if(showCrossair){
// horizontal line
line(
selectorParams.image,
Point((int)selectorParams.box.x,(int)(selectorParams.box.y+selectorParams.box.height/2)),
Point((int)(selectorParams.box.x+selectorParams.box.width),(int)(selectorParams.box.y+selectorParams.box.height/2)),
Scalar(255,0,0),2,1
);
// vertical line
line(
selectorParams.image,
Point((int)(selectorParams.box.x+selectorParams.box.width/2),(int)selectorParams.box.y),
Point((int)(selectorParams.box.x+selectorParams.box.width/2),(int)(selectorParams.box.y+selectorParams.box.height)),
Scalar(255,0,0),2,1
);
}
// show the image bouding box
imshow(windowName,selectorParams.image);
// reset the image
selectorParams.image=img.clone();
//get keyboard event
key=waitKey(1);
}
return selectorParams.box;
}
void ROISelector::select(const std::string& windowName, Mat img, std::vector<Rect2d> & boundingBox, bool fromCenter){
std::vector<Rect2d> box;
Rect2d temp;
key=0;
// show notice to user
printf("Select an object to track and then press SPACE or ENTER button!\n" );
printf("Finish the selection process by pressing BACKSPACE button!\n" );
// while key is not Backspace
while(key!=27){
temp=select(windowName, img, true, fromCenter);
if(temp.width>0 && temp.height>0)
box.push_back(temp);
}
boundingBox=box;
}
ROISelector _selector;
Rect2d selectROI(Mat img, bool fromCenter){
return _selector.select("ROI selector", img, true, fromCenter);
};
Rect2d selectROI(const std::string& windowName, Mat img, bool showCrossair, bool fromCenter){
printf("Select an object to track and then press SPACE or ENTER button!\n" );
return _selector.select(windowName,img, showCrossair, fromCenter);
};
void selectROI(const std::string& windowName, Mat img, std::vector<Rect2d> & boundingBox, bool fromCenter){
return _selector.select(windowName, img, boundingBox, fromCenter);
}
} /* namespace cv */
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment