Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv_contrib
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv_contrib
Commits
ffa6637b
Commit
ffa6637b
authored
Aug 26, 2015
by
Vadim Pisarevsky
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #300 from kurnianggoro:multitracker
parents
60f5e5ef
a805f8ba
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
592 additions
and
0 deletions
+592
-0
diagrams.markdown
modules/tracking/doc/diagrams.markdown
+31
-0
tracker.hpp
modules/tracking/include/opencv2/tracking/tracker.hpp
+112
-0
multitracker.cpp
modules/tracking/samples/multitracker.cpp
+145
-0
multiTracker.cpp
modules/tracking/src/multiTracker.cpp
+120
-0
roiSelector.cpp
modules/tracking/src/roiSelector.cpp
+184
-0
No files found.
modules/tracking/doc/diagrams.markdown
View file @
ffa6637b
...
...
@@ -223,3 +223,34 @@ TrackerSampler diagram
}
@enduml
MultiTracker diagram
======================
@startuml{tracking_uml_multiple.png}
package "MultiTracker"
package "Tracker"
MultiTracker -> Tracker: create
note top of Tracker: Several classes can be generated.
@enduml
@startuml{multi_tracker_uml.png}
class MultiTracker{
MultiTracker(const String& trackerType = "" );
~MultiTracker();
+bool add( const Mat& image, const Rect2d& boundingBox );
+bool add( const String& trackerType, const Mat& image, const Rect2d& boundingBox );
+bool add(const String& trackerType, const Mat& image, std::vector
<Rect2d>
boundingBox);
+bool add(const Mat& image, std::vector
<Rect2d>
boundingBox);
+bool update( const Mat& image, std::vector
<Rect2d>
& boundingBox );
+std::vector
<Rect2d>
objects;
---
#std::vector
<
Ptr
<
Tracker
>
> trackerList;
#String defaultAlgorithm;
}
@enduml
modules/tracking/include/opencv2/tracking/tracker.hpp
View file @
ffa6637b
...
...
@@ -1243,6 +1243,118 @@ class CV_EXPORTS_W TrackerKCF : public Tracker
BOILERPLATE_CODE
(
"KCF"
,
TrackerKCF
);
};
/************************************ MultiTracker Class ************************************/
/** @brief This class is used to track multiple objects using the specified tracker algorithm.
* The MultiTracker is naive implementation of multiple object tracking.
* It process the tracked objects independently without any optimization accross the tracked objects.
*/
class
CV_EXPORTS_W
MultiTracker
{
public
:
/**
* \brief Constructor.
* In the case of trackerType is given, it will be set as the default algorithm for all trackers.
* @param trackerType the name of the tracker algorithm to be used
*/
MultiTracker
(
const
String
&
trackerType
=
""
);
/**
* \brief Destructor
*/
~
MultiTracker
();
/**
* \brief Add a new object to be tracked.
* The defaultAlgorithm will be used the newly added tracker.
* @param image input image
* @param boundingBox a rectangle represents ROI of the tracked object
*/
bool
add
(
const
Mat
&
image
,
const
Rect2d
&
boundingBox
);
/**
* \brief Add a new object to be tracked.
* @param trackerType the name of the tracker algorithm to be used
* @param image input image
* @param boundingBox a rectangle represents ROI of the tracked object
*/
bool
add
(
const
String
&
trackerType
,
const
Mat
&
image
,
const
Rect2d
&
boundingBox
);
/**
* \brief Add a set of objects to be tracked.
* @param trackerType the name of the tracker algorithm to be used
* @param image input image
* @param boundingBox list of the tracked objects
*/
bool
add
(
const
String
&
trackerType
,
const
Mat
&
image
,
std
::
vector
<
Rect2d
>
boundingBox
);
/**
* \brief Add a set of objects to be tracked using the defaultAlgorithm tracker.
* @param image input image
* @param boundingBox list of the tracked objects
*/
bool
add
(
const
Mat
&
image
,
std
::
vector
<
Rect2d
>
boundingBox
);
/**
* \brief Update the current tracking status.
* The result will be saved in the internal storage.
* @param image input image
*/
bool
update
(
const
Mat
&
image
);
//!< storage for the tracked objects, each object corresponds to one tracker algorithm.
std
::
vector
<
Rect2d
>
objects
;
/**
* \brief Update the current tracking status.
* @param image input image
* @param boundingBox the tracking result, represent a list of ROIs of the tracked objects.
*/
bool
update
(
const
Mat
&
image
,
std
::
vector
<
Rect2d
>
&
boundingBox
);
protected
:
//!< storage for the tracker algorithms.
std
::
vector
<
Ptr
<
Tracker
>
>
trackerList
;
//!< default algorithm for the tracking method.
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 */
...
...
modules/tracking/samples/multitracker.cpp
0 → 100644
View file @
ffa6637b
/*----------------------------------------------
* Usage:
* example_tracking_multitracker <video_name> [algorithm]
*
* example:
* example_tracking_multitracker Bolt/img/%04d.jpg
* example_tracking_multitracker faceocc2.webm KCF
*
* Note: after the OpenCV libary is installed,
* please re-compile this code with "HAVE_OPENCV" parameter activated
* to enable the high precission of fps computation
*--------------------------------------------------*/
/* after the OpenCV libary is installed
* please uncomment the the line below and re-compile this code
* to enable high precission of fps computation
*/
//#define HAVE_OPENCV
#include <opencv2/core/utility.hpp>
#include <opencv2/tracking.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <cstring>
#include <ctime>
#ifdef HAVE_OPENCV
#include <opencv2/flann.hpp>
#endif
#define RESET "\033[0m"
#define RED "\033[31m"
/* Red */
#define GREEN "\033[32m"
/* Green */
using
namespace
std
;
using
namespace
cv
;
int
main
(
int
argc
,
char
**
argv
){
// show help
if
(
argc
<
2
){
cout
<<
" Usage: example_tracking_multitracker <video_name> [algorithm]
\n
"
" examples:
\n
"
" example_tracking_multitracker Bolt/img/%04d.jpg
\n
"
" example_tracking_multitracker faceocc2.webm MEDIANFLOW
\n
"
"
\n
"
" Note: after the OpenCV libary is installed,
\n
"
" please re-compile with the HAVE_OPENCV parameter activated
\n
"
" to enable the high precission of fps computation.
\n
"
<<
endl
;
return
0
;
}
// timer
#ifdef HAVE_OPENCV
cvflann
::
StartStopTimer
timer
;
#else
clock_t
timer
;
#endif
// for showing the speed
double
fps
;
std
::
string
text
;
char
buffer
[
50
];
// set the default tracking algorithm
std
::
string
trackingAlg
=
"KCF"
;
// set the tracking algorithm from parameter
if
(
argc
>
2
)
trackingAlg
=
argv
[
2
];
// create the tracker
MultiTracker
trackers
(
trackingAlg
);
// container of the tracked objects
vector
<
Rect2d
>
objects
;
// set input video
std
::
string
video
=
argv
[
1
];
VideoCapture
cap
(
video
);
Mat
frame
;
// get bounding box
cap
>>
frame
;
selectROI
(
"tracker"
,
frame
,
objects
);
//quit when the tracked object(s) is not provided
if
(
objects
.
size
()
<
1
)
return
0
;
// initialize the tracker
trackers
.
add
(
frame
,
objects
);
// do the tracking
printf
(
GREEN
"Start the tracking process, press ESC to quit.
\n
"
RESET
);
for
(
;;
){
// get frame from the video
cap
>>
frame
;
// stop the program if no more images
if
(
frame
.
rows
==
0
||
frame
.
cols
==
0
)
break
;
// start the timer
#ifdef HAVE_OPENCV
timer
.
start
();
#else
timer
=
clock
();
#endif
//update the tracking result
trackers
.
update
(
frame
);
// calculate the processing speed
#ifdef HAVE_OPENCV
timer
.
stop
();
fps
=
1.0
/
timer
.
value
;
timer
.
reset
();
#else
timer
=
clock
();
trackers
.
update
(
frame
);
timer
=
clock
()
-
timer
;
fps
=
(
double
)
CLOCKS_PER_SEC
/
(
double
)
timer
;
#endif
// draw the tracked object
for
(
unsigned
i
=
0
;
i
<
trackers
.
objects
.
size
();
i
++
)
rectangle
(
frame
,
trackers
.
objects
[
i
],
Scalar
(
255
,
0
,
0
),
2
,
1
);
// draw the processing speed
sprintf
(
buffer
,
"speed: %.0f fps"
,
fps
);
text
=
buffer
;
putText
(
frame
,
text
,
Point
(
20
,
20
),
FONT_HERSHEY_PLAIN
,
1
,
Scalar
(
255
,
255
,
255
));
// show image with the tracked object
imshow
(
"tracker"
,
frame
);
//quit on ESC button
if
(
waitKey
(
1
)
==
27
)
break
;
}
}
modules/tracking/src/multiTracker.cpp
0 → 100644
View file @
ffa6637b
/*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
{
// constructor
MultiTracker
::
MultiTracker
(
const
String
&
trackerType
)
:
defaultAlgorithm
(
trackerType
){};
// destructor
MultiTracker
::~
MultiTracker
(){};
// add an object to be tracked, defaultAlgorithm is used
bool
MultiTracker
::
add
(
const
Mat
&
image
,
const
Rect2d
&
boundingBox
){
// quit if defaultAlgorithm has not been configured
if
(
defaultAlgorithm
==
""
){
printf
(
"Default algorithm was not defined!
\n
"
);
return
false
;
}
// add a new tracked object
return
add
(
defaultAlgorithm
.
c_str
(),
image
,
boundingBox
);
};
// add a new tracked object
bool
MultiTracker
::
add
(
const
String
&
trackerType
,
const
Mat
&
image
,
const
Rect2d
&
boundingBox
){
// declare a new tracker
Ptr
<
Tracker
>
newTracker
=
Tracker
::
create
(
trackerType
);
// add the created tracker algorithm to the trackers list
trackerList
.
push_back
(
newTracker
);
// add the ROI to the bounding box list
objects
.
push_back
(
boundingBox
);
// initialize the created tracker
return
trackerList
.
back
()
->
init
(
image
,
boundingBox
);
};
// add a set of objects to be tracked
bool
MultiTracker
::
add
(
const
String
&
trackerType
,
const
Mat
&
image
,
std
::
vector
<
Rect2d
>
boundingBox
){
// status of the tracker addition
bool
stat
=
false
;
// add tracker for all input objects
for
(
unsigned
i
=
0
;
i
<
boundingBox
.
size
();
i
++
){
stat
=
add
(
trackerType
,
image
,
boundingBox
[
i
]);
if
(
!
stat
)
break
;
}
// return the status
return
stat
;
};
// add a set of object to be tracked, defaultAlgorithm is used.
bool
MultiTracker
::
add
(
const
Mat
&
image
,
std
::
vector
<
Rect2d
>
boundingBox
){
// quit if defaultAlgorithm has not been configured
if
(
defaultAlgorithm
==
""
){
printf
(
"Default algorithm was not defined!
\n
"
);
return
false
;
}
return
add
(
defaultAlgorithm
.
c_str
(),
image
,
boundingBox
);
};
// update position of the tracked objects, the result is stored in internal storage
bool
MultiTracker
::
update
(
const
Mat
&
image
){
for
(
unsigned
i
=
0
;
i
<
trackerList
.
size
();
i
++
){
trackerList
[
i
]
->
update
(
image
,
objects
[
i
]);
}
return
true
;
};
// update position of the tracked objects, the result is copied to external variable
bool
MultiTracker
::
update
(
const
Mat
&
image
,
std
::
vector
<
Rect2d
>
&
boundingBox
){
update
(
image
);
boundingBox
=
objects
;
return
true
;
};
}
/* namespace cv */
modules/tracking/src/roiSelector.cpp
0 → 100644
View file @
ffa6637b
/*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 */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment