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
4e14e8c8
Commit
4e14e8c8
authored
Aug 05, 2014
by
Alex Leontiev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
coding style
parent
ed4aeef7
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
552 additions
and
493 deletions
+552
-493
tld_tracker.cpp
modules/tracking/src/tld_tracker.cpp
+345
-319
tld_tracker.hpp
modules/tracking/src/tld_tracker.hpp
+35
-28
tld_utils.cpp
modules/tracking/src/tld_utils.cpp
+172
-146
No files found.
modules/tracking/src/tld_tracker.cpp
View file @
4e14e8c8
...
@@ -62,7 +62,7 @@
...
@@ -62,7 +62,7 @@
#define DOWNSCALE_MODE INTER_LINEAR
#define DOWNSCALE_MODE INTER_LINEAR
#define BLUR_AS_VADIM
#define BLUR_AS_VADIM
#undef CLOSED_LOOP
#undef CLOSED_LOOP
static
const
cv
::
Size
GaussBlurKernelSize
(
3
,
3
);
static
const
cv
::
Size
GaussBlurKernelSize
(
3
,
3
);
using
namespace
cv
;
using
namespace
cv
;
using
namespace
tld
;
using
namespace
tld
;
...
@@ -88,18 +88,12 @@ using namespace tld;
...
@@ -88,18 +88,12 @@ using namespace tld;
* 11. group decls logically, order of statements
* 11. group decls logically, order of statements
*
*
* ?10. all in one class
* ?10. all in one class
* todo: initializer lists
* todo: initializer lists; const methods
*
* format: if,while,for, , Assert
* format: methods
* --> compile
* ; ,
* --> compile
* -->commit-push -->notify
*
*
* ?( )
* ?( )
*
*
* ?vadim: for{1command} can omit {}; if( a != (b + c) ) vs ( a != ( b + c ) )
* ?vadim: for{1command} can omit {}; if( a != (b + c) ) vs ( a != ( b + c ) ); if{} for{} method{} oneline:spaces, omit{};
* 1-statement for/if without {}
*/
*/
/* design decisions:
/* design decisions:
...
@@ -109,24 +103,24 @@ namespace cv
...
@@ -109,24 +103,24 @@ namespace cv
{
{
class
TLDDetector
;
class
TLDDetector
;
class
MyMouseCallbackDEBUG
{
class
MyMouseCallbackDEBUG
{
public
:
public
:
MyMouseCallbackDEBUG
(
Mat
&
img
,
Mat
&
imgBlurred
,
TLDDetector
*
detector
)
:
img_
(
img
),
imgBlurred_
(
imgBlurred
),
detector_
(
detector
){}
MyMouseCallbackDEBUG
(
Mat
&
img
,
Mat
&
imgBlurred
,
TLDDetector
*
detector
)
:
img_
(
img
),
imgBlurred_
(
imgBlurred
),
detector_
(
detector
){}
static
void
onMouse
(
int
event
,
int
x
,
int
y
,
int
,
void
*
obj
){
static
void
onMouse
(
int
event
,
int
x
,
int
y
,
int
,
void
*
obj
){
((
MyMouseCallbackDEBUG
*
)
obj
)
->
onMouse
(
event
,
x
,
y
);
}
((
MyMouseCallbackDEBUG
*
)
obj
)
->
onMouse
(
event
,
x
,
y
);
MyMouseCallbackDEBUG
&
operator
=
(
const
MyMouseCallbackDEBUG
&
/*other*/
){
return
*
this
;
}
}
MyMouseCallbackDEBUG
&
operator
=
(
const
MyMouseCallbackDEBUG
&
/*other*/
){
return
*
this
;}
private
:
private
:
void
onMouse
(
int
event
,
int
x
,
int
y
);
void
onMouse
(
int
event
,
int
x
,
int
y
);
Mat
&
img_
,
imgBlurred_
;
Mat
&
img_
,
imgBlurred_
;
TLDDetector
*
detector_
;
TLDDetector
*
detector_
;
};
};
class
Data
{
class
Data
{
public
:
public
:
Data
(
Rect2d
initBox
);
Data
(
Rect2d
initBox
);
Size
getMinSize
(){
return
minSize
;
}
Size
getMinSize
(){
return
minSize
;
}
double
getScale
(){
return
scale
;
}
double
getScale
(){
return
scale
;
}
bool
confident
;
bool
confident
;
bool
failedLastTime
;
bool
failedLastTime
;
int
frameNum
;
int
frameNum
;
...
@@ -136,35 +130,39 @@ private:
...
@@ -136,35 +130,39 @@ private:
Size
minSize
;
Size
minSize
;
};
};
class
TLDDetector
{
class
TLDDetector
{
public
:
public
:
TLDDetector
(
const
TrackerTLD
::
Params
&
params
,
Ptr
<
TrackerModel
>
model_in
)
:
model
(
model_in
),
params_
(
params
){}
TLDDetector
(
const
TrackerTLD
::
Params
&
params
,
Ptr
<
TrackerModel
>
model_in
)
:
model
(
model_in
),
params_
(
params
){}
~
TLDDetector
(){}
~
TLDDetector
(){}
static
void
generateScanGrid
(
int
rows
,
int
cols
,
Size
initBox
,
std
::
vector
<
Rect2d
>&
res
,
bool
withScaling
=
false
);
static
void
generateScanGrid
(
int
rows
,
int
cols
,
Size
initBox
,
std
::
vector
<
Rect2d
>&
res
,
bool
withScaling
=
false
);
struct
LabeledPatch
{
struct
LabeledPatch
{
Rect2d
rect
;
Rect2d
rect
;
bool
isObject
,
shouldBeIntegrated
;
bool
isObject
,
shouldBeIntegrated
;
};
};
bool
detect
(
const
Mat
&
img
,
const
Mat
&
imgBlurred
,
Rect2d
&
res
,
std
::
vector
<
LabeledPatch
>&
patches
);
bool
detect
(
const
Mat
&
img
,
const
Mat
&
imgBlurred
,
Rect2d
&
res
,
std
::
vector
<
LabeledPatch
>&
patches
);
protected
:
protected
:
friend
class
MyMouseCallbackDEBUG
;
friend
class
MyMouseCallbackDEBUG
;
Ptr
<
TrackerModel
>
model
;
Ptr
<
TrackerModel
>
model
;
void
computeIntegralImages
(
const
Mat
&
img
,
Mat_
<
double
>&
intImgP
,
Mat_
<
double
>&
intImgP2
){
integral
(
img
,
intImgP
,
intImgP2
,
CV_64F
);
}
void
computeIntegralImages
(
const
Mat
&
img
,
Mat_
<
double
>&
intImgP
,
Mat_
<
double
>&
intImgP2
){
integral
(
img
,
intImgP
,
intImgP2
,
CV_64F
);
}
inline
bool
patchVariance
(
Mat_
<
double
>&
intImgP
,
Mat_
<
double
>&
intImgP2
,
double
originalVariance
,
Point
pt
,
Size
size
);
inline
bool
patchVariance
(
Mat_
<
double
>&
intImgP
,
Mat_
<
double
>&
intImgP2
,
double
originalVariance
,
Point
pt
,
Size
size
);
TrackerTLD
::
Params
params_
;
TrackerTLD
::
Params
params_
;
};
};
template
<
class
T
,
class
Tparams
>
template
<
class
T
,
class
Tparams
>
class
TrackerProxyImpl
:
public
TrackerProxy
{
class
TrackerProxyImpl
:
public
TrackerProxy
{
public
:
public
:
TrackerProxyImpl
(
Tparams
params
=
Tparams
())
:
params_
(
params
){}
TrackerProxyImpl
(
Tparams
params
=
Tparams
())
:
params_
(
params
){}
bool
init
(
const
Mat
&
image
,
const
Rect2d
&
boundingBox
){
bool
init
(
const
Mat
&
image
,
const
Rect2d
&
boundingBox
)
{
trackerPtr
=
T
::
createTracker
();
trackerPtr
=
T
::
createTracker
();
return
trackerPtr
->
init
(
image
,
boundingBox
);
return
trackerPtr
->
init
(
image
,
boundingBox
);
}
}
bool
update
(
const
Mat
&
image
,
Rect2d
&
boundingBox
){
bool
update
(
const
Mat
&
image
,
Rect2d
&
boundingBox
)
return
trackerPtr
->
update
(
image
,
boundingBox
);
{
return
trackerPtr
->
update
(
image
,
boundingBox
);
}
}
private
:
private
:
Ptr
<
T
>
trackerPtr
;
Ptr
<
T
>
trackerPtr
;
...
@@ -172,53 +170,55 @@ private:
...
@@ -172,53 +170,55 @@ private:
Rect2d
boundingBox_
;
Rect2d
boundingBox_
;
};
};
class
TrackerTLDModel
:
public
TrackerModel
{
class
TrackerTLDModel
:
public
TrackerModel
public
:
{
TrackerTLDModel
(
TrackerTLD
::
Params
params
,
const
Mat
&
image
,
const
Rect2d
&
boundingBox
,
Size
minSize
);
public
:
Rect2d
getBoundingBox
(){
return
boundingBox_
;}
TrackerTLDModel
(
TrackerTLD
::
Params
params
,
const
Mat
&
image
,
const
Rect2d
&
boundingBox
,
Size
minSize
);
void
setBoudingBox
(
Rect2d
boundingBox
){
boundingBox_
=
boundingBox
;}
Rect2d
getBoundingBox
(){
return
boundingBox_
;
}
double
getOriginalVariance
(){
return
originalVariance_
;}
void
setBoudingBox
(
Rect2d
boundingBox
){
boundingBox_
=
boundingBox
;
}
double
getOriginalVariance
(){
return
originalVariance_
;
}
inline
double
ensembleClassifierNum
(
const
uchar
*
data
);
inline
double
ensembleClassifierNum
(
const
uchar
*
data
);
inline
void
prepareClassifiers
(
int
rowstep
){
for
(
int
i
=
0
;
i
<
(
int
)
classifiers
.
size
();
i
++
)
classifiers
[
i
].
prepareClassifier
(
rowstep
);
}
inline
void
prepareClassifiers
(
int
rowstep
){
for
(
int
i
=
0
;
i
<
(
int
)
classifiers
.
size
();
i
++
)
classifiers
[
i
].
prepareClassifier
(
rowstep
);
}
double
Sr
(
const
Mat_
<
uchar
>&
patch
);
double
Sr
(
const
Mat_
<
uchar
>&
patch
);
double
Sc
(
const
Mat_
<
uchar
>&
patch
);
double
Sc
(
const
Mat_
<
uchar
>&
patch
);
void
integrateRelabeled
(
Mat
&
img
,
Mat
&
imgBlurred
,
const
std
::
vector
<
TLDDetector
::
LabeledPatch
>&
patches
);
void
integrateRelabeled
(
Mat
&
img
,
Mat
&
imgBlurred
,
const
std
::
vector
<
TLDDetector
::
LabeledPatch
>&
patches
);
void
integrateAdditional
(
const
std
::
vector
<
Mat_
<
uchar
>
>&
eForModel
,
const
std
::
vector
<
Mat_
<
uchar
>
>&
eForEnsemble
,
bool
isPositive
);
void
integrateAdditional
(
const
std
::
vector
<
Mat_
<
uchar
>
>&
eForModel
,
const
std
::
vector
<
Mat_
<
uchar
>
>&
eForEnsemble
,
bool
isPositive
);
Size
getMinSize
(){
return
minSize_
;
}
Size
getMinSize
(){
return
minSize_
;
}
void
printme
(
FILE
*
port
=
stdout
);
void
printme
(
FILE
*
port
=
stdout
);
protected
:
protected
:
Size
minSize_
;
Size
minSize_
;
int
timeStampPositiveNext
,
timeStampNegativeNext
;
int
timeStampPositiveNext
,
timeStampNegativeNext
;
TrackerTLD
::
Params
params_
;
TrackerTLD
::
Params
params_
;
void
pushIntoModel
(
const
Mat_
<
uchar
>&
example
,
bool
positive
);
void
pushIntoModel
(
const
Mat_
<
uchar
>&
example
,
bool
positive
);
void
modelEstimationImpl
(
const
std
::
vector
<
Mat
>&
/*responses*/
){}
void
modelEstimationImpl
(
const
std
::
vector
<
Mat
>&
/*responses*/
){}
void
modelUpdateImpl
(){}
void
modelUpdateImpl
(){}
Rect2d
boundingBox_
;
Rect2d
boundingBox_
;
double
originalVariance_
;
double
originalVariance_
;
std
::
vector
<
Mat_
<
uchar
>
>
positiveExamples
,
negativeExamples
;
std
::
vector
<
Mat_
<
uchar
>
>
positiveExamples
,
negativeExamples
;
std
::
vector
<
int
>
timeStampsPositive
,
timeStampsNegative
;
std
::
vector
<
int
>
timeStampsPositive
,
timeStampsNegative
;
RNG
rng
;
RNG
rng
;
std
::
vector
<
TLDEnsembleClassifier
>
classifiers
;
std
::
vector
<
TLDEnsembleClassifier
>
classifiers
;
};
};
class
TrackerTLDImpl
:
public
TrackerTLD
class
TrackerTLDImpl
:
public
TrackerTLD
{
{
public
:
public
:
TrackerTLDImpl
(
const
TrackerTLD
::
Params
&
parameters
=
TrackerTLD
::
Params
()
);
TrackerTLDImpl
(
const
TrackerTLD
::
Params
&
parameters
=
TrackerTLD
::
Params
()
);
void
read
(
const
FileNode
&
fn
);
void
read
(
const
FileNode
&
fn
);
void
write
(
FileStorage
&
fs
)
const
;
void
write
(
FileStorage
&
fs
)
const
;
protected
:
protected
:
class
Pexpert
{
class
Pexpert
{
public
:
public
:
Pexpert
(
const
Mat
&
img
,
const
Mat
&
imgBlurred
,
Rect2d
&
resultBox
,
const
TLDDetector
*
detector
,
TrackerTLD
::
Params
params
,
Size
initSize
)
:
Pexpert
(
const
Mat
&
img
,
const
Mat
&
imgBlurred
,
Rect2d
&
resultBox
,
const
TLDDetector
*
detector
,
TrackerTLD
::
Params
params
,
Size
initSize
)
:
img_
(
img
),
imgBlurred_
(
imgBlurred
),
resultBox_
(
resultBox
),
detector_
(
detector
),
params_
(
params
),
initSize_
(
initSize
){}
img_
(
img
),
imgBlurred_
(
imgBlurred
),
resultBox_
(
resultBox
),
detector_
(
detector
),
params_
(
params
),
initSize_
(
initSize
){}
bool
operator
()(
Rect2d
/*box*/
){
return
false
;
}
bool
operator
()(
Rect2d
/*box*/
){
return
false
;
}
int
additionalExamples
(
std
::
vector
<
Mat_
<
uchar
>
>&
examplesForModel
,
std
::
vector
<
Mat_
<
uchar
>
>&
examplesForEnsemble
);
int
additionalExamples
(
std
::
vector
<
Mat_
<
uchar
>
>&
examplesForModel
,
std
::
vector
<
Mat_
<
uchar
>
>&
examplesForEnsemble
);
protected
:
protected
:
Pexpert
(){}
Pexpert
(){}
Mat
img_
,
imgBlurred_
;
Mat
img_
,
imgBlurred_
;
Rect2d
resultBox_
;
Rect2d
resultBox_
;
const
TLDDetector
*
detector_
;
const
TLDDetector
*
detector_
;
TrackerTLD
::
Params
params_
;
TrackerTLD
::
Params
params_
;
...
@@ -226,17 +226,22 @@ class TrackerTLDImpl : public TrackerTLD
...
@@ -226,17 +226,22 @@ class TrackerTLDImpl : public TrackerTLD
Size
initSize_
;
Size
initSize_
;
};
};
class
Nexpert
:
public
Pexpert
{
class
Nexpert
:
public
Pexpert
{
public
:
public
:
Nexpert
(
const
Mat
&
img
,
Rect2d
&
resultBox
,
const
TLDDetector
*
detector
,
TrackerTLD
::
Params
params
){
Nexpert
(
const
Mat
&
img
,
Rect2d
&
resultBox
,
const
TLDDetector
*
detector
,
TrackerTLD
::
Params
params
)
img_
=
img
;
resultBox_
=
resultBox
;
detector_
=
detector
;
params_
=
params
;}
{
img_
=
img
;
resultBox_
=
resultBox
;
detector_
=
detector
;
params_
=
params
;
}
bool
operator
()(
Rect2d
box
);
bool
operator
()(
Rect2d
box
);
int
additionalExamples
(
std
::
vector
<
Mat_
<
uchar
>
>&
examplesForModel
,
std
::
vector
<
Mat_
<
uchar
>
>&
examplesForEnsemble
){
int
additionalExamples
(
std
::
vector
<
Mat_
<
uchar
>
>&
examplesForModel
,
std
::
vector
<
Mat_
<
uchar
>
>&
examplesForEnsemble
)
examplesForModel
.
clear
();
examplesForEnsemble
.
clear
();
return
0
;}
{
examplesForModel
.
clear
();
examplesForEnsemble
.
clear
();
return
0
;
}
};
};
bool
initImpl
(
const
Mat
&
image
,
const
Rect2d
&
boundingBox
);
bool
initImpl
(
const
Mat
&
image
,
const
Rect2d
&
boundingBox
);
bool
updateImpl
(
const
Mat
&
image
,
Rect2d
&
boundingBox
);
bool
updateImpl
(
const
Mat
&
image
,
Rect2d
&
boundingBox
);
TrackerTLD
::
Params
params
;
TrackerTLD
::
Params
params
;
Ptr
<
Data
>
data
;
Ptr
<
Data
>
data
;
...
@@ -244,75 +249,74 @@ class TrackerTLDImpl : public TrackerTLD
...
@@ -244,75 +249,74 @@ class TrackerTLDImpl : public TrackerTLD
Ptr
<
TLDDetector
>
detector
;
Ptr
<
TLDDetector
>
detector
;
};
};
TrackerTLD
::
Params
::
Params
(){}
TrackerTLD
::
Params
::
Params
(){
void
TrackerTLD
::
Params
::
read
(
const
cv
::
FileNode
&
/*fn*/
){}
}
void
TrackerTLD
::
Params
::
read
(
const
cv
::
FileNode
&
/*fn*/
){
}
void
TrackerTLD
::
Params
::
write
(
cv
::
FileStorage
&
/*fs*/
)
const
{
void
TrackerTLD
::
Params
::
write
(
cv
::
FileStorage
&
/*fs*/
)
const
{}
}
Ptr
<
TrackerTLD
>
TrackerTLD
::
createTracker
(
const
TrackerTLD
::
Params
&
parameters
){
Ptr
<
TrackerTLD
>
TrackerTLD
::
createTracker
(
const
TrackerTLD
::
Params
&
parameters
)
{
return
Ptr
<
TrackerTLDImpl
>
(
new
TrackerTLDImpl
(
parameters
));
return
Ptr
<
TrackerTLDImpl
>
(
new
TrackerTLDImpl
(
parameters
));
}
}
TrackerTLDImpl
::
TrackerTLDImpl
(
const
TrackerTLD
::
Params
&
parameters
)
:
TrackerTLDImpl
::
TrackerTLDImpl
(
const
TrackerTLD
::
Params
&
parameters
)
:
params
(
parameters
){
params
(
parameters
)
{
isInit
=
false
;
isInit
=
false
;
trackerProxy
=
Ptr
<
TrackerProxyImpl
<
TrackerMedianFlow
,
TrackerMedianFlow
::
Params
>
>
trackerProxy
=
Ptr
<
TrackerProxyImpl
<
TrackerMedianFlow
,
TrackerMedianFlow
::
Params
>
>
(
new
TrackerProxyImpl
<
TrackerMedianFlow
,
TrackerMedianFlow
::
Params
>
());
(
new
TrackerProxyImpl
<
TrackerMedianFlow
,
TrackerMedianFlow
::
Params
>
());
}
}
void
TrackerTLDImpl
::
read
(
const
cv
::
FileNode
&
fn
)
void
TrackerTLDImpl
::
read
(
const
cv
::
FileNode
&
fn
)
{
{
params
.
read
(
fn
);
params
.
read
(
fn
);
}
}
void
TrackerTLDImpl
::
write
(
cv
::
FileStorage
&
fs
)
const
void
TrackerTLDImpl
::
write
(
cv
::
FileStorage
&
fs
)
const
{
{
params
.
write
(
fs
);
params
.
write
(
fs
);
}
}
bool
TrackerTLDImpl
::
initImpl
(
const
Mat
&
image
,
const
Rect2d
&
boundingBox
){
bool
TrackerTLDImpl
::
initImpl
(
const
Mat
&
image
,
const
Rect2d
&
boundingBox
)
{
Mat
image_gray
;
Mat
image_gray
;
trackerProxy
->
init
(
image
,
boundingBox
);
trackerProxy
->
init
(
image
,
boundingBox
);
cvtColor
(
image
,
image_gray
,
COLOR_BGR2GRAY
);
cvtColor
(
image
,
image_gray
,
COLOR_BGR2GRAY
);
data
=
Ptr
<
Data
>
(
new
Data
(
boundingBox
));
data
=
Ptr
<
Data
>
(
new
Data
(
boundingBox
));
double
scale
=
data
->
getScale
();
double
scale
=
data
->
getScale
();
Rect2d
myBoundingBox
=
boundingBox
;
Rect2d
myBoundingBox
=
boundingBox
;
if
(
scale
>
1.0
)
if
(
scale
>
1.0
)
{
{
Mat
image_proxy
;
Mat
image_proxy
;
resize
(
image_gray
,
image_proxy
,
Size
(
cvRound
(
image
.
cols
*
scale
),
cvRound
(
image
.
rows
*
scale
)),
0
,
0
,
DOWNSCALE_MODE
);
resize
(
image_gray
,
image_proxy
,
Size
(
cvRound
(
image
.
cols
*
scale
),
cvRound
(
image
.
rows
*
scale
)),
0
,
0
,
DOWNSCALE_MODE
);
image_proxy
.
copyTo
(
image_gray
);
image_proxy
.
copyTo
(
image_gray
);
myBoundingBox
.
x
*=
scale
;
myBoundingBox
.
x
*=
scale
;
myBoundingBox
.
y
*=
scale
;
myBoundingBox
.
y
*=
scale
;
myBoundingBox
.
width
*=
scale
;
myBoundingBox
.
width
*=
scale
;
myBoundingBox
.
height
*=
scale
;
myBoundingBox
.
height
*=
scale
;
}
}
model
=
Ptr
<
TrackerTLDModel
>
(
new
TrackerTLDModel
(
params
,
image_gray
,
myBoundingBox
,
data
->
getMinSize
()));
model
=
Ptr
<
TrackerTLDModel
>
(
new
TrackerTLDModel
(
params
,
image_gray
,
myBoundingBox
,
data
->
getMinSize
()));
detector
=
Ptr
<
TLDDetector
>
(
new
TLDDetector
(
params
,
model
));
detector
=
Ptr
<
TLDDetector
>
(
new
TLDDetector
(
params
,
model
));
data
->
confident
=
false
;
data
->
confident
=
false
;
data
->
failedLastTime
=
false
;
data
->
failedLastTime
=
false
;
return
true
;
return
true
;
}
}
bool
TrackerTLDImpl
::
updateImpl
(
const
Mat
&
image
,
Rect2d
&
boundingBox
){
bool
TrackerTLDImpl
::
updateImpl
(
const
Mat
&
image
,
Rect2d
&
boundingBox
)
Mat
image_gray
,
image_blurred
,
imageForDetector
;
{
Mat
image_gray
,
image_blurred
,
imageForDetector
;
cvtColor
(
image
,
image_gray
,
COLOR_BGR2GRAY
);
cvtColor
(
image
,
image_gray
,
COLOR_BGR2GRAY
);
double
scale
=
data
->
getScale
();
double
scale
=
data
->
getScale
();
if
(
scale
>
1.0
){
if
(
scale
>
1.0
)
resize
(
image_gray
,
imageForDetector
,
Size
(
cvRound
(
image
.
cols
*
scale
),
cvRound
(
image
.
rows
*
scale
)),
0
,
0
,
DOWNSCALE_MODE
);
resize
(
image_gray
,
imageForDetector
,
Size
(
cvRound
(
image
.
cols
*
scale
),
cvRound
(
image
.
rows
*
scale
)),
0
,
0
,
DOWNSCALE_MODE
);
}
else
{
else
imageForDetector
=
image_gray
;
imageForDetector
=
image_gray
;
}
GaussianBlur
(
imageForDetector
,
image_blurred
,
GaussBlurKernelSize
,
0.0
);
GaussianBlur
(
imageForDetector
,
image_blurred
,
GaussBlurKernelSize
,
0.0
);
TrackerTLDModel
*
tldModel
=
((
TrackerTLDModel
*
)
static_cast
<
TrackerModel
*>
(
model
));
TrackerTLDModel
*
tldModel
=
((
TrackerTLDModel
*
)
static_cast
<
TrackerModel
*>
(
model
));
data
->
frameNum
++
;
data
->
frameNum
++
;
Mat_
<
uchar
>
standardPatch
(
STANDARD_PATCH_SIZE
,
STANDARD_PATCH_SIZE
);
Mat_
<
uchar
>
standardPatch
(
STANDARD_PATCH_SIZE
,
STANDARD_PATCH_SIZE
);
std
::
vector
<
TLDDetector
::
LabeledPatch
>
detectorResults
;
std
::
vector
<
TLDDetector
::
LabeledPatch
>
detectorResults
;
//best overlap around 92%
//best overlap around 92%
...
@@ -322,169 +326,187 @@ bool TrackerTLDImpl::updateImpl(const Mat& image, Rect2d& boundingBox){
...
@@ -322,169 +326,187 @@ bool TrackerTLDImpl::updateImpl(const Mat& image, Rect2d& boundingBox){
for
(
int
i
=
0
;
i
<
2
;
i
++
)
for
(
int
i
=
0
;
i
<
2
;
i
++
)
{
{
Rect2d
tmpCandid
=
boundingBox
;
Rect2d
tmpCandid
=
boundingBox
;
if
(((
i
==
0
)
&&
!
(
data
->
failedLastTime
)
&&
trackerProxy
->
update
(
image
,
tmpCandid
))
||
if
(
(
(
i
==
0
)
&&
!
(
data
->
failedLastTime
)
&&
trackerProxy
->
update
(
image
,
tmpCandid
)
)
||
((
i
==
1
)
&&
(
detector
->
detect
(
imageForDetector
,
image_blurred
,
tmpCandid
,
detectorResults
)))){
(
(
i
==
1
)
&&
detector
->
detect
(
imageForDetector
,
image_blurred
,
tmpCandid
,
detectorResults
)
)
)
{
candidates
.
push_back
(
tmpCandid
);
candidates
.
push_back
(
tmpCandid
);
if
(
i
==
0
){
if
(
i
==
0
)
resample
(
image_gray
,
tmpCandid
,
standardPatch
);
resample
(
image_gray
,
tmpCandid
,
standardPatch
);
}
else
{
else
resample
(
imageForDetector
,
tmpCandid
,
standardPatch
);
resample
(
imageForDetector
,
tmpCandid
,
standardPatch
);
}
candidatesRes
.
push_back
(
tldModel
->
Sc
(
standardPatch
));
candidatesRes
.
push_back
(
tldModel
->
Sc
(
standardPatch
));
}
else
{
}
if
(
i
==
0
){
else
{
if
(
i
==
0
)
trackerNeedsReInit
=
true
;
trackerNeedsReInit
=
true
;
}
}
}
}
}
std
::
vector
<
double
>::
iterator
it
=
std
::
max_element
(
candidatesRes
.
begin
(),
candidatesRes
.
end
());
std
::
vector
<
double
>::
iterator
it
=
std
::
max_element
(
candidatesRes
.
begin
(),
candidatesRes
.
end
());
dfprintf
((
stdout
,
"scale = %f
\n
"
,
log
(
1.0
*
boundingBox
.
width
/
(
data
->
getMinSize
()).
width
)
/
log
(
SCALE_STEP
)));
dfprintf
((
stdout
,
"scale = %f
\n
"
,
log
(
1.0
*
boundingBox
.
width
/
(
data
->
getMinSize
()).
width
)
/
log
(
SCALE_STEP
)));
for
(
int
i
=
0
;
i
<
(
int
)
candidatesRes
.
size
();
i
++
){
for
(
int
i
=
0
;
i
<
(
int
)
candidatesRes
.
size
();
i
++
)
dprintf
((
"
\t
candidatesRes[%d] = %f
\n
"
,
i
,
candidatesRes
[
i
]));
dprintf
((
"
\t
candidatesRes[%d] = %f
\n
"
,
i
,
candidatesRes
[
i
]));
}
data
->
printme
();
data
->
printme
();
tldModel
->
printme
(
stdout
);
tldModel
->
printme
(
stdout
);
if
(
it
==
candidatesRes
.
end
()){
if
(
it
==
candidatesRes
.
end
()
)
{
data
->
confident
=
false
;
data
->
confident
=
false
;
data
->
failedLastTime
=
true
;
data
->
failedLastTime
=
true
;
return
false
;
return
false
;
}
else
{
}
else
{
boundingBox
=
candidates
[
it
-
candidatesRes
.
begin
()];
boundingBox
=
candidates
[
it
-
candidatesRes
.
begin
()];
data
->
failedLastTime
=
false
;
data
->
failedLastTime
=
false
;
if
(
trackerNeedsReInit
||
it
!=
candidatesRes
.
begin
()){
if
(
trackerNeedsReInit
||
it
!=
candidatesRes
.
begin
()
)
trackerProxy
->
init
(
image
,
boundingBox
);
trackerProxy
->
init
(
image
,
boundingBox
);
}
}
}
#if 1
#if 1
if
(
it
!=
candidatesRes
.
end
()){
if
(
it
!=
candidatesRes
.
end
()
)
resample
(
imageForDetector
,
candidates
[
it
-
candidatesRes
.
begin
()],
standardPatch
);
{
dfprintf
((
stderr
,
"%d %f %f
\n
"
,
data
->
frameNum
,
tldModel
->
Sc
(
standardPatch
),
tldModel
->
Sr
(
standardPatch
)));
resample
(
imageForDetector
,
candidates
[
it
-
candidatesRes
.
begin
()],
standardPatch
);
if
(
candidatesRes
.
size
()
==
2
&&
it
==
(
candidatesRes
.
begin
()
+
1
))
dfprintf
((
stderr
,
"%d %f %f
\n
"
,
data
->
frameNum
,
tldModel
->
Sc
(
standardPatch
),
tldModel
->
Sr
(
standardPatch
)));
dfprintf
((
stderr
,
"detector WON
\n
"
));
if
(
candidatesRes
.
size
()
==
2
&&
it
==
(
candidatesRes
.
begin
()
+
1
)
)
}
else
{
dfprintf
((
stderr
,
"detector WON
\n
"
));
dfprintf
((
stderr
,
"%d x x
\n
"
,
data
->
frameNum
));
}
else
{
dfprintf
((
stderr
,
"%d x x
\n
"
,
data
->
frameNum
));
}
}
#endif
#endif
if
(
*
it
>
CORE_THRESHOLD
){
if
(
*
it
>
CORE_THRESHOLD
)
data
->
confident
=
true
;
data
->
confident
=
true
;
}
if
(
data
->
confident
){
if
(
data
->
confident
)
Pexpert
pExpert
(
imageForDetector
,
image_blurred
,
boundingBox
,
detector
,
params
,
data
->
getMinSize
());
{
Nexpert
nExpert
(
imageForDetector
,
boundingBox
,
detector
,
params
);
Pexpert
pExpert
(
imageForDetector
,
image_blurred
,
boundingBox
,
detector
,
params
,
data
->
getMinSize
());
std
::
vector
<
Mat_
<
uchar
>
>
examplesForModel
,
examplesForEnsemble
;
Nexpert
nExpert
(
imageForDetector
,
boundingBox
,
detector
,
params
);
examplesForModel
.
reserve
(
100
);
examplesForEnsemble
.
reserve
(
100
);
std
::
vector
<
Mat_
<
uchar
>
>
examplesForModel
,
examplesForEnsemble
;
examplesForModel
.
reserve
(
100
);
examplesForEnsemble
.
reserve
(
100
);
int
negRelabeled
=
0
;
int
negRelabeled
=
0
;
for
(
int
i
=
0
;
i
<
(
int
)
detectorResults
.
size
();
i
++
){
for
(
int
i
=
0
;
i
<
(
int
)
detectorResults
.
size
();
i
++
)
{
bool
expertResult
;
bool
expertResult
;
if
(
detectorResults
[
i
].
isObject
){
if
(
detectorResults
[
i
].
isObject
)
{
expertResult
=
nExpert
(
detectorResults
[
i
].
rect
);
expertResult
=
nExpert
(
detectorResults
[
i
].
rect
);
if
(
expertResult
!=
detectorResults
[
i
].
isObject
){
negRelabeled
++
;}
if
(
expertResult
!=
detectorResults
[
i
].
isObject
){
negRelabeled
++
;
}
}
else
{
}
else
{
expertResult
=
pExpert
(
detectorResults
[
i
].
rect
);
expertResult
=
pExpert
(
detectorResults
[
i
].
rect
);
}
}
detectorResults
[
i
].
shouldBeIntegrated
=
detectorResults
[
i
].
shouldBeIntegrated
||
(
detectorResults
[
i
].
isObject
!=
expertResult
);
detectorResults
[
i
].
shouldBeIntegrated
=
detectorResults
[
i
].
shouldBeIntegrated
||
(
detectorResults
[
i
].
isObject
!=
expertResult
);
detectorResults
[
i
].
isObject
=
expertResult
;
detectorResults
[
i
].
isObject
=
expertResult
;
}
}
tldModel
->
integrateRelabeled
(
imageForDetector
,
image_blurred
,
detectorResults
);
tldModel
->
integrateRelabeled
(
imageForDetector
,
image_blurred
,
detectorResults
);
dprintf
((
"%d relabeled by nExpert
\n
"
,
negRelabeled
));
dprintf
((
"%d relabeled by nExpert
\n
"
,
negRelabeled
));
pExpert
.
additionalExamples
(
examplesForModel
,
examplesForEnsemble
);
pExpert
.
additionalExamples
(
examplesForModel
,
examplesForEnsemble
);
tldModel
->
integrateAdditional
(
examplesForModel
,
examplesForEnsemble
,
true
);
tldModel
->
integrateAdditional
(
examplesForModel
,
examplesForEnsemble
,
true
);
examplesForModel
.
clear
();
examplesForEnsemble
.
clear
();
examplesForModel
.
clear
();
examplesForEnsemble
.
clear
();
nExpert
.
additionalExamples
(
examplesForModel
,
examplesForEnsemble
);
nExpert
.
additionalExamples
(
examplesForModel
,
examplesForEnsemble
);
tldModel
->
integrateAdditional
(
examplesForModel
,
examplesForEnsemble
,
false
);
tldModel
->
integrateAdditional
(
examplesForModel
,
examplesForEnsemble
,
false
);
}
else
{
}
else
{
#ifdef CLOSED_LOOP
#ifdef CLOSED_LOOP
tldModel
->
integrateRelabeled
(
imageForDetector
,
image_blurred
,
detectorResults
);
tldModel
->
integrateRelabeled
(
imageForDetector
,
image_blurred
,
detectorResults
);
#endif
#endif
}
}
return
true
;
return
true
;
}
}
TrackerTLDModel
::
TrackerTLDModel
(
TrackerTLD
::
Params
params
,
const
Mat
&
image
,
const
Rect2d
&
boundingBox
,
Size
minSize
)
:
minSize_
(
minSize
),
TrackerTLDModel
::
TrackerTLDModel
(
TrackerTLD
::
Params
params
,
const
Mat
&
image
,
const
Rect2d
&
boundingBox
,
Size
minSize
)
:
minSize_
(
minSize
),
timeStampPositiveNext
(
0
),
timeStampNegativeNext
(
0
),
params_
(
params
),
boundingBox_
(
boundingBox
){
timeStampPositiveNext
(
0
),
timeStampNegativeNext
(
0
),
params_
(
params
),
boundingBox_
(
boundingBox
)
{
originalVariance_
=
variance
(
image
(
boundingBox
));
originalVariance_
=
variance
(
image
(
boundingBox
));
std
::
vector
<
Rect2d
>
closest
,
scanGrid
;
std
::
vector
<
Rect2d
>
closest
,
scanGrid
;
Mat
scaledImg
,
blurredImg
,
image_blurred
;
Mat
scaledImg
,
blurredImg
,
image_blurred
;
double
scale
=
scaleAndBlur
(
image
,
cvRound
(
log
(
1.0
*
boundingBox
.
width
/
(
minSize
.
width
))
/
log
(
SCALE_STEP
)),
double
scale
=
scaleAndBlur
(
image
,
cvRound
(
log
(
1.0
*
boundingBox
.
width
/
(
minSize
.
width
))
/
log
(
SCALE_STEP
)),
scaledImg
,
blurredImg
,
GaussBlurKernelSize
,
SCALE_STEP
);
scaledImg
,
blurredImg
,
GaussBlurKernelSize
,
SCALE_STEP
);
GaussianBlur
(
image
,
image_blurred
,
GaussBlurKernelSize
,
0.0
);
GaussianBlur
(
image
,
image_blurred
,
GaussBlurKernelSize
,
0.0
);
TLDDetector
::
generateScanGrid
(
image
.
rows
,
image
.
cols
,
minSize
,
scanGrid
);
TLDDetector
::
generateScanGrid
(
image
.
rows
,
image
.
cols
,
minSize
,
scanGrid
);
getClosestN
(
scanGrid
,
Rect2d
(
boundingBox
.
x
/
scale
,
boundingBox
.
y
/
scale
,
boundingBox
.
width
/
scale
,
boundingBox
.
height
/
scale
),
10
,
closest
);
getClosestN
(
scanGrid
,
Rect2d
(
boundingBox
.
x
/
scale
,
boundingBox
.
y
/
scale
,
boundingBox
.
width
/
scale
,
boundingBox
.
height
/
scale
),
10
,
closest
);
Mat_
<
uchar
>
blurredPatch
(
minSize
);
Mat_
<
uchar
>
blurredPatch
(
minSize
);
TLDEnsembleClassifier
::
makeClassifiers
(
minSize
,
MEASURES_PER_CLASSIFIER
,
GRIDSIZE
,
classifiers
);
TLDEnsembleClassifier
::
makeClassifiers
(
minSize
,
MEASURES_PER_CLASSIFIER
,
GRIDSIZE
,
classifiers
);
positiveExamples
.
reserve
(
200
);
positiveExamples
.
reserve
(
200
);
for
(
int
i
=
0
;
i
<
(
int
)
closest
.
size
();
i
++
){
for
(
int
i
=
0
;
i
<
(
int
)
closest
.
size
();
i
++
)
for
(
int
j
=
0
;
j
<
20
;
j
++
){
{
for
(
int
j
=
0
;
j
<
20
;
j
++
)
{
Point2f
center
;
Point2f
center
;
Size2f
size
;
Size2f
size
;
Mat_
<
uchar
>
standardPatch
(
STANDARD_PATCH_SIZE
,
STANDARD_PATCH_SIZE
);
Mat_
<
uchar
>
standardPatch
(
STANDARD_PATCH_SIZE
,
STANDARD_PATCH_SIZE
);
center
.
x
=
(
float
)(
closest
[
i
].
x
+
closest
[
i
].
width
*
(
0.5
+
rng
.
uniform
(
-
0.01
,
0.01
)));
center
.
x
=
(
float
)(
closest
[
i
].
x
+
closest
[
i
].
width
*
(
0.5
+
rng
.
uniform
(
-
0.01
,
0.01
)));
center
.
y
=
(
float
)(
closest
[
i
].
y
+
closest
[
i
].
height
*
(
0.5
+
rng
.
uniform
(
-
0.01
,
0.01
)));
center
.
y
=
(
float
)(
closest
[
i
].
y
+
closest
[
i
].
height
*
(
0.5
+
rng
.
uniform
(
-
0.01
,
0.01
)));
size
.
width
=
(
float
)(
closest
[
i
].
width
*
rng
.
uniform
((
double
)
0.99
,(
double
)
1.01
));
size
.
width
=
(
float
)(
closest
[
i
].
width
*
rng
.
uniform
((
double
)
0.99
,
(
double
)
1.01
));
size
.
height
=
(
float
)(
closest
[
i
].
height
*
rng
.
uniform
((
double
)
0.99
,(
double
)
1.01
));
size
.
height
=
(
float
)(
closest
[
i
].
height
*
rng
.
uniform
((
double
)
0.99
,
(
double
)
1.01
));
float
angle
=
(
float
)
rng
.
uniform
(
-
10.0
,
10.0
);
float
angle
=
(
float
)
rng
.
uniform
(
-
10.0
,
10.0
);
resample
(
scaledImg
,
RotatedRect
(
center
,
size
,
angle
),
standardPatch
);
resample
(
scaledImg
,
RotatedRect
(
center
,
size
,
angle
),
standardPatch
);
for
(
int
y
=
0
;
y
<
standardPatch
.
rows
;
y
++
){
for
(
int
y
=
0
;
y
<
standardPatch
.
rows
;
y
++
)
for
(
int
x
=
0
;
x
<
standardPatch
.
cols
;
x
++
){
{
standardPatch
(
x
,
y
)
+=
(
uchar
)
rng
.
gaussian
(
5.0
);
for
(
int
x
=
0
;
x
<
standardPatch
.
cols
;
x
++
)
{
standardPatch
(
x
,
y
)
+=
(
uchar
)
rng
.
gaussian
(
5.0
);
}
}
}
}
#ifdef BLUR_AS_VADIM
#ifdef BLUR_AS_VADIM
GaussianBlur
(
standardPatch
,
blurredPatch
,
GaussBlurKernelSize
,
0.0
);
GaussianBlur
(
standardPatch
,
blurredPatch
,
GaussBlurKernelSize
,
0.0
);
resize
(
blurredPatch
,
blurredPatch
,
minSize
);
resize
(
blurredPatch
,
blurredPatch
,
minSize
);
#else
#else
resample
(
blurredImg
,
RotatedRect
(
center
,
size
,
angle
),
blurredPatch
);
resample
(
blurredImg
,
RotatedRect
(
center
,
size
,
angle
),
blurredPatch
);
#endif
#endif
pushIntoModel
(
standardPatch
,
true
);
pushIntoModel
(
standardPatch
,
true
);
for
(
int
k
=
0
;
k
<
(
int
)
classifiers
.
size
();
k
++
){
for
(
int
k
=
0
;
k
<
(
int
)
classifiers
.
size
();
k
++
)
classifiers
[
k
].
integrate
(
blurredPatch
,
true
);
classifiers
[
k
].
integrate
(
blurredPatch
,
true
);
}
}
}
}
}
TLDDetector
::
generateScanGrid
(
image
.
rows
,
image
.
cols
,
minSize
,
scanGrid
,
true
);
TLDDetector
::
generateScanGrid
(
image
.
rows
,
image
.
cols
,
minSize
,
scanGrid
,
true
);
negativeExamples
.
clear
();
negativeExamples
.
clear
();
negativeExamples
.
reserve
(
NEG_EXAMPLES_IN_INIT_MODEL
);
negativeExamples
.
reserve
(
NEG_EXAMPLES_IN_INIT_MODEL
);
std
::
vector
<
int
>
indices
;
std
::
vector
<
int
>
indices
;
indices
.
reserve
(
NEG_EXAMPLES_IN_INIT_MODEL
);
indices
.
reserve
(
NEG_EXAMPLES_IN_INIT_MODEL
);
while
(
negativeExamples
.
size
()
<
NEG_EXAMPLES_IN_INIT_MODEL
){
while
(
negativeExamples
.
size
()
<
NEG_EXAMPLES_IN_INIT_MODEL
)
int
i
=
rng
.
uniform
((
int
)
0
,(
int
)
scanGrid
.
size
());
{
if
(
std
::
find
(
indices
.
begin
(),
indices
.
end
(),
i
)
==
indices
.
end
()
&&
overlap
(
boundingBox
,
scanGrid
[
i
])
<
0.2
){
int
i
=
rng
.
uniform
((
int
)
0
,
(
int
)
scanGrid
.
size
());
Mat_
<
uchar
>
standardPatch
(
STANDARD_PATCH_SIZE
,
STANDARD_PATCH_SIZE
);
if
(
std
::
find
(
indices
.
begin
(),
indices
.
end
(),
i
)
==
indices
.
end
()
&&
overlap
(
boundingBox
,
scanGrid
[
i
])
<
NEXPERT_THRESHOLD
)
resample
(
image
,
scanGrid
[
i
],
standardPatch
);
{
pushIntoModel
(
standardPatch
,
false
);
Mat_
<
uchar
>
standardPatch
(
STANDARD_PATCH_SIZE
,
STANDARD_PATCH_SIZE
);
resample
(
image
,
scanGrid
[
i
],
standardPatch
);
resample
(
image_blurred
,
scanGrid
[
i
],
blurredPatch
);
pushIntoModel
(
standardPatch
,
false
);
for
(
int
k
=
0
;
k
<
(
int
)
classifiers
.
size
();
k
++
){
classifiers
[
k
].
integrate
(
blurredPatch
,
false
);
resample
(
image_blurred
,
scanGrid
[
i
],
blurredPatch
);
}
for
(
int
k
=
0
;
k
<
(
int
)
classifiers
.
size
();
k
++
)
classifiers
[
k
].
integrate
(
blurredPatch
,
false
);
}
}
}
}
dprintf
((
"positive patches: %d
\n
negative patches: %d
\n
"
,
(
int
)
positiveExamples
.
size
(),
(
int
)
negativeExamples
.
size
()));
dprintf
((
"positive patches: %d
\n
negative patches: %d
\n
"
,
(
int
)
positiveExamples
.
size
(),
(
int
)
negativeExamples
.
size
()));
}
}
void
TLDDetector
::
generateScanGrid
(
int
rows
,
int
cols
,
Size
initBox
,
std
::
vector
<
Rect2d
>&
res
,
bool
withScaling
){
void
TLDDetector
::
generateScanGrid
(
int
rows
,
int
cols
,
Size
initBox
,
std
::
vector
<
Rect2d
>&
res
,
bool
withScaling
)
{
res
.
clear
();
res
.
clear
();
//scales step: SCALE_STEP; hor step: 10% of width; verstep: 10% of height; minsize: 20pix
//scales step: SCALE_STEP; hor step: 10% of width; verstep: 10% of height; minsize: 20pix
for
(
double
h
=
initBox
.
height
,
w
=
initBox
.
width
;
h
<
cols
&&
w
<
rows
;){
for
(
double
h
=
initBox
.
height
,
w
=
initBox
.
width
;
h
<
cols
&&
w
<
rows
;
)
for
(
double
x
=
0
;
(
x
+
w
+
1.0
)
<=
cols
;
x
+=
(
0.1
*
w
))
{
for
(
double
x
=
0
;
(
x
+
w
+
1.0
)
<=
cols
;
x
+=
(
0.1
*
w
)
)
{
{
for
(
double
y
=
0
;
(
y
+
h
+
1.0
)
<=
rows
;
y
+=
(
0.1
*
h
)
)
for
(
double
y
=
0
;
(
y
+
h
+
1.0
)
<=
rows
;
y
+=
(
0.1
*
h
)
)
res
.
push_back
(
Rect2d
(
x
,
y
,
w
,
h
));
res
.
push_back
(
Rect2d
(
x
,
y
,
w
,
h
));
}
}
if
(
withScaling
)
if
(
withScaling
)
{
{
...
@@ -494,7 +516,7 @@ void TLDDetector::generateScanGrid(int rows,int cols,Size initBox,std::vector<Re
...
@@ -494,7 +516,7 @@ void TLDDetector::generateScanGrid(int rows,int cols,Size initBox,std::vector<Re
if
(
h
<
20
||
w
<
20
)
if
(
h
<
20
||
w
<
20
)
{
{
h
=
initBox
.
height
*
SCALE_STEP
;
w
=
initBox
.
width
*
SCALE_STEP
;
h
=
initBox
.
height
*
SCALE_STEP
;
w
=
initBox
.
width
*
SCALE_STEP
;
CV_Assert
(
h
>
initBox
.
height
||
w
>
initBox
.
width
);
CV_Assert
(
h
>
initBox
.
height
||
w
>
initBox
.
width
);
}
}
}
}
else
else
...
@@ -507,61 +529,66 @@ void TLDDetector::generateScanGrid(int rows,int cols,Size initBox,std::vector<Re
...
@@ -507,61 +529,66 @@ void TLDDetector::generateScanGrid(int rows,int cols,Size initBox,std::vector<Re
break
;
break
;
}
}
}
}
dprintf
((
"%d rects in res
\n
"
,(
int
)
res
.
size
()));
dprintf
((
"%d rects in res
\n
"
,
(
int
)
res
.
size
()));
}
}
bool
TLDDetector
::
detect
(
const
Mat
&
img
,
const
Mat
&
imgBlurred
,
Rect2d
&
res
,
std
::
vector
<
LabeledPatch
>&
patches
){
bool
TLDDetector
::
detect
(
const
Mat
&
img
,
const
Mat
&
imgBlurred
,
Rect2d
&
res
,
std
::
vector
<
LabeledPatch
>&
patches
)
{
TrackerTLDModel
*
tldModel
=
((
TrackerTLDModel
*
)
static_cast
<
TrackerModel
*>
(
model
));
TrackerTLDModel
*
tldModel
=
((
TrackerTLDModel
*
)
static_cast
<
TrackerModel
*>
(
model
));
Size
initSize
=
tldModel
->
getMinSize
();
Size
initSize
=
tldModel
->
getMinSize
();
patches
.
clear
();
patches
.
clear
();
Mat
resized_img
,
blurred_img
;
Mat
resized_img
,
blurred_img
;
Mat_
<
uchar
>
standardPatch
(
STANDARD_PATCH_SIZE
,
STANDARD_PATCH_SIZE
);
Mat_
<
uchar
>
standardPatch
(
STANDARD_PATCH_SIZE
,
STANDARD_PATCH_SIZE
);
img
.
copyTo
(
resized_img
);
img
.
copyTo
(
resized_img
);
imgBlurred
.
copyTo
(
blurred_img
);
imgBlurred
.
copyTo
(
blurred_img
);
double
originalVariance
=
tldModel
->
getOriginalVariance
();;
double
originalVariance
=
tldModel
->
getOriginalVariance
();
;
int
dx
=
initSize
.
width
/
10
,
dy
=
initSize
.
height
/
10
;
int
dx
=
initSize
.
width
/
10
,
dy
=
initSize
.
height
/
10
;
Size2d
size
=
img
.
size
();
Size2d
size
=
img
.
size
();
double
scale
=
1.0
;
double
scale
=
1.0
;
int
total
=
0
,
pass
=
0
;
int
total
=
0
,
pass
=
0
;
int
npos
=
0
,
nneg
=
0
;
int
npos
=
0
,
nneg
=
0
;
double
tmp
=
0
,
maxSc
=
-
5.0
;
double
tmp
=
0
,
maxSc
=
-
5.0
;
Rect2d
maxScRect
;
Rect2d
maxScRect
;
START_TICK
(
"detector"
);
START_TICK
(
"detector"
);
do
do
{
{
Mat_
<
double
>
intImgP
,
intImgP2
;
Mat_
<
double
>
intImgP
,
intImgP2
;
computeIntegralImages
(
resized_img
,
intImgP
,
intImgP2
);
computeIntegralImages
(
resized_img
,
intImgP
,
intImgP2
);
tldModel
->
prepareClassifiers
((
int
)
blurred_img
.
step
[
0
]);
tldModel
->
prepareClassifiers
((
int
)
blurred_img
.
step
[
0
]);
for
(
int
i
=
0
,
imax
=
cvFloor
((
0.0
+
resized_img
.
cols
-
initSize
.
width
)
/
dx
);
i
<
imax
;
i
++
){
for
(
int
i
=
0
,
imax
=
cvFloor
((
0.0
+
resized_img
.
cols
-
initSize
.
width
)
/
dx
);
i
<
imax
;
i
++
)
for
(
int
j
=
0
,
jmax
=
cvFloor
((
0.0
+
resized_img
.
rows
-
initSize
.
height
)
/
dy
);
j
<
jmax
;
j
++
){
{
for
(
int
j
=
0
,
jmax
=
cvFloor
((
0.0
+
resized_img
.
rows
-
initSize
.
height
)
/
dy
);
j
<
jmax
;
j
++
)
{
LabeledPatch
labPatch
;
LabeledPatch
labPatch
;
total
++
;
total
++
;
if
(
!
patchVariance
(
intImgP
,
intImgP2
,
originalVariance
,
Point
(
dx
*
i
,
dy
*
j
),
initSize
)){
if
(
!
patchVariance
(
intImgP
,
intImgP2
,
originalVariance
,
Point
(
dx
*
i
,
dy
*
j
),
initSize
)
)
continue
;
continue
;
}
if
(
tldModel
->
ensembleClassifierNum
(
&
blurred_img
.
at
<
uchar
>
(
dy
*
j
,
dx
*
i
))
<=
ENSEMBLE_THRESHOLD
)
if
(
!
(
tldModel
->
ensembleClassifierNum
(
&
blurred_img
.
at
<
uchar
>
(
dy
*
j
,
dx
*
i
))
>
ENSEMBLE_THRESHOLD
)){
continue
;
continue
;
}
pass
++
;
pass
++
;
labPatch
.
rect
=
Rect2d
(
dx
*
i
*
scale
,
dy
*
j
*
scale
,
initSize
.
width
*
scale
,
initSize
.
height
*
scale
);
labPatch
.
rect
=
Rect2d
(
dx
*
i
*
scale
,
dy
*
j
*
scale
,
initSize
.
width
*
scale
,
initSize
.
height
*
scale
);
resample
(
resized_img
,
Rect2d
(
Point
(
dx
*
i
,
dy
*
j
),
initSize
),
standardPatch
);
resample
(
resized_img
,
Rect2d
(
Point
(
dx
*
i
,
dy
*
j
),
initSize
),
standardPatch
);
tmp
=
tldModel
->
Sr
(
standardPatch
);
tmp
=
tldModel
->
Sr
(
standardPatch
);
labPatch
.
isObject
=
tmp
>
THETA_NN
;
labPatch
.
isObject
=
tmp
>
THETA_NN
;
labPatch
.
shouldBeIntegrated
=
abs
(
tmp
-
THETA_NN
)
<
0.1
;
labPatch
.
shouldBeIntegrated
=
abs
(
tmp
-
THETA_NN
)
<
0.1
;
patches
.
push_back
(
labPatch
);
patches
.
push_back
(
labPatch
);
if
(
!
labPatch
.
isObject
){
if
(
!
labPatch
.
isObject
)
{
nneg
++
;
nneg
++
;
continue
;
continue
;
}
else
{
}
else
{
npos
++
;
npos
++
;
}
}
tmp
=
tldModel
->
Sc
(
standardPatch
);
tmp
=
tldModel
->
Sc
(
standardPatch
);
if
(
tmp
>
maxSc
){
if
(
tmp
>
maxSc
)
{
maxSc
=
tmp
;
maxSc
=
tmp
;
maxScRect
=
labPatch
.
rect
;
maxScRect
=
labPatch
.
rect
;
}
}
...
@@ -571,53 +598,54 @@ bool TLDDetector::detect(const Mat& img,const Mat& imgBlurred,Rect2d& res,std::v
...
@@ -571,53 +598,54 @@ bool TLDDetector::detect(const Mat& img,const Mat& imgBlurred,Rect2d& res,std::v
size
.
width
/=
SCALE_STEP
;
size
.
width
/=
SCALE_STEP
;
size
.
height
/=
SCALE_STEP
;
size
.
height
/=
SCALE_STEP
;
scale
*=
SCALE_STEP
;
scale
*=
SCALE_STEP
;
resize
(
img
,
resized_img
,
size
,
0
,
0
,
DOWNSCALE_MODE
);
resize
(
img
,
resized_img
,
size
,
0
,
0
,
DOWNSCALE_MODE
);
GaussianBlur
(
resized_img
,
blurred_img
,
GaussBlurKernelSize
,
0.0
f
);
GaussianBlur
(
resized_img
,
blurred_img
,
GaussBlurKernelSize
,
0.0
f
);
}
}
while
(
size
.
width
>=
initSize
.
width
&&
size
.
height
>=
initSize
.
height
);
while
(
size
.
width
>=
initSize
.
width
&&
size
.
height
>=
initSize
.
height
);
END_TICK
(
"detector"
);
END_TICK
(
"detector"
);
dfprintf
((
stdout
,
"after NCC: nneg = %d npos = %d
\n
"
,
nneg
,
npos
));
dfprintf
((
stdout
,
"after NCC: nneg = %d npos = %d
\n
"
,
nneg
,
npos
));
#if !0
#if !0
std
::
vector
<
Rect2d
>
poss
,
negs
;
std
::
vector
<
Rect2d
>
poss
,
negs
;
for
(
int
i
=
0
;
i
<
(
int
)
patches
.
size
();
i
++
){
for
(
int
i
=
0
;
i
<
(
int
)
patches
.
size
();
i
++
)
if
(
patches
[
i
].
isObject
)
{
if
(
patches
[
i
].
isObject
)
poss
.
push_back
(
patches
[
i
].
rect
);
poss
.
push_back
(
patches
[
i
].
rect
);
else
else
negs
.
push_back
(
patches
[
i
].
rect
);
negs
.
push_back
(
patches
[
i
].
rect
);
}
}
dfprintf
((
stdout
,
"%d pos and %d neg
\n
"
,(
int
)
poss
.
size
(),
(
int
)
negs
.
size
()));
dfprintf
((
stdout
,
"%d pos and %d neg
\n
"
,
(
int
)
poss
.
size
(),
(
int
)
negs
.
size
()));
drawWithRects
(
img
,
negs
,
poss
,
"tech"
);
drawWithRects
(
img
,
negs
,
poss
,
"tech"
);
#endif
#endif
dfprintf
((
stdout
,
"%d after ensemble
\n
"
,
pass
));
dfprintf
((
stdout
,
"%d after ensemble
\n
"
,
pass
));
if
(
maxSc
<
0
){
if
(
maxSc
<
0
)
return
false
;
return
false
;
}
res
=
maxScRect
;
res
=
maxScRect
;
return
true
;
return
true
;
}
}
/** Computes the variance of subimage given by box, with the help of two integral
/** Computes the variance of subimage given by box, with the help of two integral
* images intImgP and intImgP2 (sum of squares), which should be also provided.*/
* images intImgP and intImgP2 (sum of squares), which should be also provided.*/
bool
TLDDetector
::
patchVariance
(
Mat_
<
double
>&
intImgP
,
Mat_
<
double
>&
intImgP2
,
double
originalVariance
,
Point
pt
,
Size
size
){
bool
TLDDetector
::
patchVariance
(
Mat_
<
double
>&
intImgP
,
Mat_
<
double
>&
intImgP2
,
double
originalVariance
,
Point
pt
,
Size
size
)
int
x
=
(
pt
.
x
),
y
=
(
pt
.
y
),
width
=
(
size
.
width
),
height
=
(
size
.
height
);
{
int
x
=
(
pt
.
x
),
y
=
(
pt
.
y
),
width
=
(
size
.
width
),
height
=
(
size
.
height
);
CV_Assert
(
0
<=
x
&&
(
x
+
width
)
<
intImgP
.
cols
&&
(
x
+
width
)
<
intImgP2
.
cols
);
CV_Assert
(
0
<=
x
&&
(
x
+
width
)
<
intImgP
.
cols
&&
(
x
+
width
)
<
intImgP2
.
cols
);
CV_Assert
(
0
<=
y
&&
(
y
+
height
)
<
intImgP
.
rows
&&
(
y
+
height
)
<
intImgP2
.
rows
);
CV_Assert
(
0
<=
y
&&
(
y
+
height
)
<
intImgP
.
rows
&&
(
y
+
height
)
<
intImgP2
.
rows
);
double
p
=
0
,
p2
=
0
;
double
p
=
0
,
p2
=
0
;
double
A
,
B
,
C
,
D
;
double
A
,
B
,
C
,
D
;
A
=
intImgP
(
y
,
x
);
A
=
intImgP
(
y
,
x
);
B
=
intImgP
(
y
,
x
+
width
);
B
=
intImgP
(
y
,
x
+
width
);
C
=
intImgP
(
y
+
height
,
x
);
C
=
intImgP
(
y
+
height
,
x
);
D
=
intImgP
(
y
+
height
,
x
+
width
);
D
=
intImgP
(
y
+
height
,
x
+
width
);
p
=
(
A
+
D
-
B
-
C
)
/
(
width
*
height
);
p
=
(
A
+
D
-
B
-
C
)
/
(
width
*
height
);
A
=
intImgP2
(
y
,
x
);
A
=
intImgP2
(
y
,
x
);
B
=
intImgP2
(
y
,
x
+
width
);
B
=
intImgP2
(
y
,
x
+
width
);
C
=
intImgP2
(
y
+
height
,
x
);
C
=
intImgP2
(
y
+
height
,
x
);
D
=
intImgP2
(
y
+
height
,
x
+
width
);
D
=
intImgP2
(
y
+
height
,
x
+
width
);
p2
=
(
A
+
D
-
B
-
C
)
/
(
width
*
height
);
p2
=
(
A
+
D
-
B
-
C
)
/
(
width
*
height
);
return
((
p2
-
p
*
p
)
>
VARIANCE_THRESHOLD
*
originalVariance
);
return
((
p2
-
p
*
p
)
>
VARIANCE_THRESHOLD
*
originalVariance
);
...
@@ -636,9 +664,9 @@ double TrackerTLDModel::Sr(const Mat_<uchar>& patch)
...
@@ -636,9 +664,9 @@ double TrackerTLDModel::Sr(const Mat_<uchar>& patch)
{
{
double
splus
=
0.0
,
sminus
=
0.0
;
double
splus
=
0.0
,
sminus
=
0.0
;
for
(
int
i
=
0
;
i
<
(
int
)
positiveExamples
.
size
();
i
++
)
for
(
int
i
=
0
;
i
<
(
int
)
positiveExamples
.
size
();
i
++
)
splus
=
std
::
max
(
splus
,
0.5
*
(
NCC
(
positiveExamples
[
i
],
patch
)
+
1.0
));
splus
=
std
::
max
(
splus
,
0.5
*
(
NCC
(
positiveExamples
[
i
],
patch
)
+
1.0
));
for
(
int
i
=
0
;
i
<
(
int
)
negativeExamples
.
size
();
i
++
)
for
(
int
i
=
0
;
i
<
(
int
)
negativeExamples
.
size
();
i
++
)
sminus
=
std
::
max
(
sminus
,
0.5
*
(
NCC
(
negativeExamples
[
i
],
patch
)
+
1.0
));
sminus
=
std
::
max
(
sminus
,
0.5
*
(
NCC
(
negativeExamples
[
i
],
patch
)
+
1.0
));
if
(
splus
+
sminus
==
0.0
)
if
(
splus
+
sminus
==
0.0
)
return
0.0
;
return
0.0
;
return
splus
/
(
sminus
+
splus
);
return
splus
/
(
sminus
+
splus
);
...
@@ -646,38 +674,38 @@ double TrackerTLDModel::Sr(const Mat_<uchar>& patch)
...
@@ -646,38 +674,38 @@ double TrackerTLDModel::Sr(const Mat_<uchar>& patch)
double
TrackerTLDModel
::
Sc
(
const
Mat_
<
uchar
>&
patch
)
double
TrackerTLDModel
::
Sc
(
const
Mat_
<
uchar
>&
patch
)
{
{
double
splus
=
0.0
,
sminus
=
0.0
;
double
splus
=
0.0
,
sminus
=
0.0
;
int
med
=
getMedian
(
timeStampsPositive
);
int
med
=
getMedian
(
timeStampsPositive
);
for
(
int
i
=
0
;
i
<
(
int
)
positiveExamples
.
size
();
i
++
)
for
(
int
i
=
0
;
i
<
(
int
)
positiveExamples
.
size
();
i
++
)
{
{
if
(
(
int
)
timeStampsPositive
[
i
]
<=
med
)
if
(
(
int
)
timeStampsPositive
[
i
]
<=
med
)
splus
=
std
::
max
(
splus
,
0.5
*
(
NCC
(
positiveExamples
[
i
],
patch
)
+
1.0
));
splus
=
std
::
max
(
splus
,
0.5
*
(
NCC
(
positiveExamples
[
i
],
patch
)
+
1.0
));
}
}
for
(
int
i
=
0
;
i
<
(
int
)
negativeExamples
.
size
();
i
++
)
for
(
int
i
=
0
;
i
<
(
int
)
negativeExamples
.
size
();
i
++
)
sminus
=
std
::
max
(
sminus
,
0.5
*
(
NCC
(
negativeExamples
[
i
],
patch
)
+
1.0
));
sminus
=
std
::
max
(
sminus
,
0.5
*
(
NCC
(
negativeExamples
[
i
],
patch
)
+
1.0
));
if
(
splus
+
sminus
==
0.0
)
if
(
splus
+
sminus
==
0.0
)
return
0.0
;
return
0.0
;
return
splus
/
(
sminus
+
splus
);
return
splus
/
(
sminus
+
splus
);
}
}
void
TrackerTLDModel
::
integrateRelabeled
(
Mat
&
img
,
Mat
&
imgBlurred
,
const
std
::
vector
<
TLDDetector
::
LabeledPatch
>&
patches
)
void
TrackerTLDModel
::
integrateRelabeled
(
Mat
&
img
,
Mat
&
imgBlurred
,
const
std
::
vector
<
TLDDetector
::
LabeledPatch
>&
patches
)
{
{
Mat_
<
uchar
>
standardPatch
(
STANDARD_PATCH_SIZE
,
STANDARD_PATCH_SIZE
),
blurredPatch
(
minSize_
);
Mat_
<
uchar
>
standardPatch
(
STANDARD_PATCH_SIZE
,
STANDARD_PATCH_SIZE
),
blurredPatch
(
minSize_
);
int
positiveIntoModel
=
0
,
negativeIntoModel
=
0
,
positiveIntoEnsemble
=
0
,
negativeIntoEnsemble
=
0
;
int
positiveIntoModel
=
0
,
negativeIntoModel
=
0
,
positiveIntoEnsemble
=
0
,
negativeIntoEnsemble
=
0
;
for
(
int
k
=
0
;
k
<
(
int
)
patches
.
size
();
k
++
)
for
(
int
k
=
0
;
k
<
(
int
)
patches
.
size
();
k
++
)
{
{
if
(
patches
[
k
].
shouldBeIntegrated
)
if
(
patches
[
k
].
shouldBeIntegrated
)
{
{
resample
(
img
,
patches
[
k
].
rect
,
standardPatch
);
resample
(
img
,
patches
[
k
].
rect
,
standardPatch
);
if
(
patches
[
k
].
isObject
)
if
(
patches
[
k
].
isObject
)
{
{
positiveIntoModel
++
;
positiveIntoModel
++
;
pushIntoModel
(
standardPatch
,
true
);
pushIntoModel
(
standardPatch
,
true
);
}
}
else
else
{
{
negativeIntoModel
++
;
negativeIntoModel
++
;
pushIntoModel
(
standardPatch
,
false
);
pushIntoModel
(
standardPatch
,
false
);
}
}
}
}
...
@@ -687,31 +715,29 @@ void TrackerTLDModel::integrateRelabeled(Mat& img,Mat& imgBlurred,const std::vec
...
@@ -687,31 +715,29 @@ void TrackerTLDModel::integrateRelabeled(Mat& img,Mat& imgBlurred,const std::vec
if
(
patches
[
k
].
shouldBeIntegrated
)
if
(
patches
[
k
].
shouldBeIntegrated
)
#endif
#endif
{
{
resample
(
imgBlurred
,
patches
[
k
].
rect
,
blurredPatch
);
resample
(
imgBlurred
,
patches
[
k
].
rect
,
blurredPatch
);
if
(
patches
[
k
].
isObject
)
if
(
patches
[
k
].
isObject
)
positiveIntoEnsemble
++
;
positiveIntoEnsemble
++
;
else
else
negativeIntoEnsemble
++
;
negativeIntoEnsemble
++
;
for
(
int
i
=
0
;
i
<
(
int
)
classifiers
.
size
();
i
++
)
for
(
int
i
=
0
;
i
<
(
int
)
classifiers
.
size
();
i
++
)
{
classifiers
[
i
].
integrate
(
blurredPatch
,
patches
[
k
].
isObject
);
classifiers
[
i
].
integrate
(
blurredPatch
,
patches
[
k
].
isObject
);
}
}
}
}
}
if
(
negativeIntoModel
>
0
)
if
(
negativeIntoModel
>
0
)
dfprintf
((
stdout
,
"negativeIntoModel = %d "
,
negativeIntoModel
));
dfprintf
((
stdout
,
"negativeIntoModel = %d "
,
negativeIntoModel
));
if
(
positiveIntoModel
>
0
)
if
(
positiveIntoModel
>
0
)
dfprintf
((
stdout
,
"positiveIntoModel = %d "
,
positiveIntoModel
));
dfprintf
((
stdout
,
"positiveIntoModel = %d "
,
positiveIntoModel
));
if
(
negativeIntoEnsemble
>
0
)
if
(
negativeIntoEnsemble
>
0
)
dfprintf
((
stdout
,
"negativeIntoEnsemble = %d "
,
negativeIntoEnsemble
));
dfprintf
((
stdout
,
"negativeIntoEnsemble = %d "
,
negativeIntoEnsemble
));
if
(
positiveIntoEnsemble
>
0
)
if
(
positiveIntoEnsemble
>
0
)
dfprintf
((
stdout
,
"positiveIntoEnsemble = %d "
,
positiveIntoEnsemble
));
dfprintf
((
stdout
,
"positiveIntoEnsemble = %d "
,
positiveIntoEnsemble
));
dfprintf
((
stdout
,
"
\n
"
));
dfprintf
((
stdout
,
"
\n
"
));
}
}
void
TrackerTLDModel
::
integrateAdditional
(
const
std
::
vector
<
Mat_
<
uchar
>
>&
eForModel
,
const
std
::
vector
<
Mat_
<
uchar
>
>&
eForEnsemble
,
bool
isPositive
)
void
TrackerTLDModel
::
integrateAdditional
(
const
std
::
vector
<
Mat_
<
uchar
>
>&
eForModel
,
const
std
::
vector
<
Mat_
<
uchar
>
>&
eForEnsemble
,
bool
isPositive
)
{
{
int
positiveIntoModel
=
0
,
negativeIntoModel
=
0
,
positiveIntoEnsemble
=
0
,
negativeIntoEnsemble
=
0
;
int
positiveIntoModel
=
0
,
negativeIntoModel
=
0
,
positiveIntoEnsemble
=
0
,
negativeIntoEnsemble
=
0
;
for
(
int
k
=
0
;
k
<
(
int
)
eForModel
.
size
();
k
++
)
for
(
int
k
=
0
;
k
<
(
int
)
eForModel
.
size
();
k
++
)
{
{
double
sr
=
Sr
(
eForModel
[
k
]);
double
sr
=
Sr
(
eForModel
[
k
]);
...
@@ -720,17 +746,17 @@ void TrackerTLDModel::integrateAdditional(const std::vector<Mat_<uchar> >& eForM
...
@@ -720,17 +746,17 @@ void TrackerTLDModel::integrateAdditional(const std::vector<Mat_<uchar> >& eForM
if
(
isPositive
)
if
(
isPositive
)
{
{
positiveIntoModel
++
;
positiveIntoModel
++
;
pushIntoModel
(
eForModel
[
k
],
true
);
pushIntoModel
(
eForModel
[
k
],
true
);
}
}
else
else
{
{
negativeIntoModel
++
;
negativeIntoModel
++
;
pushIntoModel
(
eForModel
[
k
],
false
);
pushIntoModel
(
eForModel
[
k
],
false
);
}
}
}
}
double
p
=
0
;
double
p
=
0
;
for
(
int
i
=
0
;
i
<
(
int
)
classifiers
.
size
();
i
++
)
for
(
int
i
=
0
;
i
<
(
int
)
classifiers
.
size
();
i
++
)
p
+=
classifiers
[
i
].
posteriorProbability
(
eForEnsemble
[
k
].
data
,(
int
)
eForEnsemble
[
k
].
step
[
0
]);
p
+=
classifiers
[
i
].
posteriorProbability
(
eForEnsemble
[
k
].
data
,
(
int
)
eForEnsemble
[
k
].
step
[
0
]);
p
/=
classifiers
.
size
();
p
/=
classifiers
.
size
();
if
(
(
p
>
ENSEMBLE_THRESHOLD
)
!=
isPositive
)
if
(
(
p
>
ENSEMBLE_THRESHOLD
)
!=
isPositive
)
{
{
...
@@ -739,32 +765,32 @@ void TrackerTLDModel::integrateAdditional(const std::vector<Mat_<uchar> >& eForM
...
@@ -739,32 +765,32 @@ void TrackerTLDModel::integrateAdditional(const std::vector<Mat_<uchar> >& eForM
else
else
negativeIntoEnsemble
++
;
negativeIntoEnsemble
++
;
for
(
int
i
=
0
;
i
<
(
int
)
classifiers
.
size
();
i
++
)
for
(
int
i
=
0
;
i
<
(
int
)
classifiers
.
size
();
i
++
)
classifiers
[
i
].
integrate
(
eForEnsemble
[
k
],
isPositive
);
classifiers
[
i
].
integrate
(
eForEnsemble
[
k
],
isPositive
);
}
}
}
}
if
(
negativeIntoModel
>
0
)
if
(
negativeIntoModel
>
0
)
dfprintf
((
stdout
,
"negativeIntoModel = %d "
,
negativeIntoModel
));
dfprintf
((
stdout
,
"negativeIntoModel = %d "
,
negativeIntoModel
));
if
(
positiveIntoModel
>
0
)
if
(
positiveIntoModel
>
0
)
dfprintf
((
stdout
,
"positiveIntoModel = %d "
,
positiveIntoModel
));
dfprintf
((
stdout
,
"positiveIntoModel = %d "
,
positiveIntoModel
));
if
(
negativeIntoEnsemble
>
0
)
if
(
negativeIntoEnsemble
>
0
)
dfprintf
((
stdout
,
"negativeIntoEnsemble = %d "
,
negativeIntoEnsemble
));
dfprintf
((
stdout
,
"negativeIntoEnsemble = %d "
,
negativeIntoEnsemble
));
if
(
positiveIntoEnsemble
>
0
)
if
(
positiveIntoEnsemble
>
0
)
dfprintf
((
stdout
,
"positiveIntoEnsemble = %d "
,
positiveIntoEnsemble
));
dfprintf
((
stdout
,
"positiveIntoEnsemble = %d "
,
positiveIntoEnsemble
));
dfprintf
((
stdout
,
"
\n
"
));
dfprintf
((
stdout
,
"
\n
"
));
}
}
int
TrackerTLDImpl
::
Pexpert
::
additionalExamples
(
std
::
vector
<
Mat_
<
uchar
>
>&
examplesForModel
,
std
::
vector
<
Mat_
<
uchar
>
>&
examplesForEnsemble
)
int
TrackerTLDImpl
::
Pexpert
::
additionalExamples
(
std
::
vector
<
Mat_
<
uchar
>
>&
examplesForModel
,
std
::
vector
<
Mat_
<
uchar
>
>&
examplesForEnsemble
)
{
{
examplesForModel
.
clear
();
examplesForEnsemble
.
clear
();
examplesForModel
.
clear
();
examplesForEnsemble
.
clear
();
examplesForModel
.
reserve
(
100
);
examplesForEnsemble
.
reserve
(
100
);
examplesForModel
.
reserve
(
100
);
examplesForEnsemble
.
reserve
(
100
);
std
::
vector
<
Rect2d
>
closest
,
scanGrid
;
std
::
vector
<
Rect2d
>
closest
,
scanGrid
;
Mat
scaledImg
,
blurredImg
;
Mat
scaledImg
,
blurredImg
;
double
scale
=
scaleAndBlur
(
img_
,
cvRound
(
log
(
1.0
*
resultBox_
.
width
/
(
initSize_
.
width
))
/
log
(
SCALE_STEP
)),
double
scale
=
scaleAndBlur
(
img_
,
cvRound
(
log
(
1.0
*
resultBox_
.
width
/
(
initSize_
.
width
))
/
log
(
SCALE_STEP
)),
scaledImg
,
blurredImg
,
GaussBlurKernelSize
,
SCALE_STEP
);
scaledImg
,
blurredImg
,
GaussBlurKernelSize
,
SCALE_STEP
);
TLDDetector
::
generateScanGrid
(
img_
.
rows
,
img_
.
cols
,
initSize_
,
scanGrid
);
TLDDetector
::
generateScanGrid
(
img_
.
rows
,
img_
.
cols
,
initSize_
,
scanGrid
);
getClosestN
(
scanGrid
,
Rect2d
(
resultBox_
.
x
/
scale
,
resultBox_
.
y
/
scale
,
resultBox_
.
width
/
scale
,
resultBox_
.
height
/
scale
),
10
,
closest
);
getClosestN
(
scanGrid
,
Rect2d
(
resultBox_
.
x
/
scale
,
resultBox_
.
y
/
scale
,
resultBox_
.
width
/
scale
,
resultBox_
.
height
/
scale
),
10
,
closest
);
for
(
int
i
=
0
;
i
<
(
int
)
closest
.
size
();
i
++
)
for
(
int
i
=
0
;
i
<
(
int
)
closest
.
size
();
i
++
)
{
{
...
@@ -772,27 +798,27 @@ int TrackerTLDImpl::Pexpert::additionalExamples(std::vector<Mat_<uchar > >& exam
...
@@ -772,27 +798,27 @@ int TrackerTLDImpl::Pexpert::additionalExamples(std::vector<Mat_<uchar > >& exam
{
{
Point2f
center
;
Point2f
center
;
Size2f
size
;
Size2f
size
;
Mat_
<
uchar
>
standardPatch
(
STANDARD_PATCH_SIZE
,
STANDARD_PATCH_SIZE
),
blurredPatch
(
initSize_
);
Mat_
<
uchar
>
standardPatch
(
STANDARD_PATCH_SIZE
,
STANDARD_PATCH_SIZE
),
blurredPatch
(
initSize_
);
center
.
x
=
(
float
)(
closest
[
i
].
x
+
closest
[
i
].
width
*
(
0.5
+
rng
.
uniform
(
-
0.01
,
0.01
)));
center
.
x
=
(
float
)(
closest
[
i
].
x
+
closest
[
i
].
width
*
(
0.5
+
rng
.
uniform
(
-
0.01
,
0.01
)));
center
.
y
=
(
float
)(
closest
[
i
].
y
+
closest
[
i
].
height
*
(
0.5
+
rng
.
uniform
(
-
0.01
,
0.01
)));
center
.
y
=
(
float
)(
closest
[
i
].
y
+
closest
[
i
].
height
*
(
0.5
+
rng
.
uniform
(
-
0.01
,
0.01
)));
size
.
width
=
(
float
)(
closest
[
i
].
width
*
rng
.
uniform
((
double
)
0.99
,(
double
)
1.01
));
size
.
width
=
(
float
)(
closest
[
i
].
width
*
rng
.
uniform
((
double
)
0.99
,
(
double
)
1.01
));
size
.
height
=
(
float
)(
closest
[
i
].
height
*
rng
.
uniform
((
double
)
0.99
,(
double
)
1.01
));
size
.
height
=
(
float
)(
closest
[
i
].
height
*
rng
.
uniform
((
double
)
0.99
,
(
double
)
1.01
));
float
angle
=
(
float
)
rng
.
uniform
(
-
5.0
,
5.0
);
float
angle
=
(
float
)
rng
.
uniform
(
-
5.0
,
5.0
);
for
(
int
y
=
0
;
y
<
standardPatch
.
rows
;
y
++
)
for
(
int
y
=
0
;
y
<
standardPatch
.
rows
;
y
++
)
{
{
for
(
int
x
=
0
;
x
<
standardPatch
.
cols
;
x
++
)
for
(
int
x
=
0
;
x
<
standardPatch
.
cols
;
x
++
)
{
{
standardPatch
(
x
,
y
)
+=
(
uchar
)
rng
.
gaussian
(
5.0
);
standardPatch
(
x
,
y
)
+=
(
uchar
)
rng
.
gaussian
(
5.0
);
}
}
}
}
#ifdef BLUR_AS_VADIM
#ifdef BLUR_AS_VADIM
GaussianBlur
(
standardPatch
,
blurredPatch
,
GaussBlurKernelSize
,
0.0
);
GaussianBlur
(
standardPatch
,
blurredPatch
,
GaussBlurKernelSize
,
0.0
);
resize
(
blurredPatch
,
blurredPatch
,
initSize_
);
resize
(
blurredPatch
,
blurredPatch
,
initSize_
);
#else
#else
resample
(
blurredImg
,
RotatedRect
(
center
,
size
,
angle
),
blurredPatch
);
resample
(
blurredImg
,
RotatedRect
(
center
,
size
,
angle
),
blurredPatch
);
#endif
#endif
resample
(
scaledImg
,
RotatedRect
(
center
,
size
,
angle
),
standardPatch
);
resample
(
scaledImg
,
RotatedRect
(
center
,
size
,
angle
),
standardPatch
);
examplesForModel
.
push_back
(
standardPatch
);
examplesForModel
.
push_back
(
standardPatch
);
examplesForEnsemble
.
push_back
(
blurredPatch
);
examplesForEnsemble
.
push_back
(
blurredPatch
);
}
}
...
@@ -802,7 +828,7 @@ int TrackerTLDImpl::Pexpert::additionalExamples(std::vector<Mat_<uchar > >& exam
...
@@ -802,7 +828,7 @@ int TrackerTLDImpl::Pexpert::additionalExamples(std::vector<Mat_<uchar > >& exam
bool
TrackerTLDImpl
::
Nexpert
::
operator
()(
Rect2d
box
)
bool
TrackerTLDImpl
::
Nexpert
::
operator
()(
Rect2d
box
)
{
{
if
(
overlap
(
resultBox_
,
box
)
<
NEXPERT_THRESHOLD
)
if
(
overlap
(
resultBox_
,
box
)
<
NEXPERT_THRESHOLD
)
return
false
;
return
false
;
else
else
return
true
;
return
true
;
...
@@ -810,31 +836,31 @@ bool TrackerTLDImpl::Nexpert::operator()(Rect2d box)
...
@@ -810,31 +836,31 @@ bool TrackerTLDImpl::Nexpert::operator()(Rect2d box)
Data
::
Data
(
Rect2d
initBox
)
Data
::
Data
(
Rect2d
initBox
)
{
{
double
minDim
=
std
::
min
(
initBox
.
width
,
initBox
.
height
);
double
minDim
=
std
::
min
(
initBox
.
width
,
initBox
.
height
);
scale
=
20.0
/
minDim
;
scale
=
20.0
/
minDim
;
minSize
.
width
=
(
int
)(
initBox
.
width
*
20.0
/
minDim
);
minSize
.
width
=
(
int
)(
initBox
.
width
*
20.0
/
minDim
);
minSize
.
height
=
(
int
)(
initBox
.
height
*
20.0
/
minDim
);
minSize
.
height
=
(
int
)(
initBox
.
height
*
20.0
/
minDim
);
frameNum
=
0
;
frameNum
=
0
;
dprintf
((
"minSize = %dx%d
\n
"
,
minSize
.
width
,
minSize
.
height
));
dprintf
((
"minSize = %dx%d
\n
"
,
minSize
.
width
,
minSize
.
height
));
}
}
void
Data
::
printme
(
FILE
*
port
)
void
Data
::
printme
(
FILE
*
port
)
{
{
dfprintf
((
port
,
"Data:
\n
"
));
dfprintf
((
port
,
"Data:
\n
"
));
dfprintf
((
port
,
"
\t
frameNum = %d
\n
"
,
frameNum
));
dfprintf
((
port
,
"
\t
frameNum = %d
\n
"
,
frameNum
));
dfprintf
((
port
,
"
\t
confident = %s
\n
"
,
confident
?
"true"
:
"false"
));
dfprintf
((
port
,
"
\t
confident = %s
\n
"
,
confident
?
"true"
:
"false"
));
dfprintf
((
port
,
"
\t
failedLastTime = %s
\n
"
,
failedLastTime
?
"true"
:
"false"
));
dfprintf
((
port
,
"
\t
failedLastTime = %s
\n
"
,
failedLastTime
?
"true"
:
"false"
));
dfprintf
((
port
,
"
\t
minSize = %dx%d
\n
"
,
minSize
.
width
,
minSize
.
height
));
dfprintf
((
port
,
"
\t
minSize = %dx%d
\n
"
,
minSize
.
width
,
minSize
.
height
));
}
}
void
TrackerTLDModel
::
printme
(
FILE
*
port
)
void
TrackerTLDModel
::
printme
(
FILE
*
port
)
{
{
dfprintf
((
port
,
"TrackerTLDModel:
\n
"
));
dfprintf
((
port
,
"TrackerTLDModel:
\n
"
));
dfprintf
((
port
,
"
\t
positiveExamples.size() = %d
\n
"
,
(
int
)
positiveExamples
.
size
()));
dfprintf
((
port
,
"
\t
positiveExamples.size() = %d
\n
"
,
(
int
)
positiveExamples
.
size
()));
dfprintf
((
port
,
"
\t
negativeExamples.size() = %d
\n
"
,
(
int
)
negativeExamples
.
size
()));
dfprintf
((
port
,
"
\t
negativeExamples.size() = %d
\n
"
,
(
int
)
negativeExamples
.
size
()));
}
}
void
MyMouseCallbackDEBUG
::
onMouse
(
int
event
,
int
x
,
int
y
)
void
MyMouseCallbackDEBUG
::
onMouse
(
int
event
,
int
x
,
int
y
)
{
{
if
(
event
==
EVENT_LBUTTONDOWN
)
if
(
event
==
EVENT_LBUTTONDOWN
)
{
{
...
@@ -842,39 +868,39 @@ void MyMouseCallbackDEBUG::onMouse( int event, int x, int y)
...
@@ -842,39 +868,39 @@ void MyMouseCallbackDEBUG::onMouse( int event, int x, int y)
img_
.
copyTo
(
imgCanvas
);
img_
.
copyTo
(
imgCanvas
);
TrackerTLDModel
*
tldModel
=
((
TrackerTLDModel
*
)
static_cast
<
TrackerModel
*>
(
detector_
->
model
));
TrackerTLDModel
*
tldModel
=
((
TrackerTLDModel
*
)
static_cast
<
TrackerModel
*>
(
detector_
->
model
));
Size
initSize
=
tldModel
->
getMinSize
();
Size
initSize
=
tldModel
->
getMinSize
();
Mat_
<
uchar
>
standardPatch
(
STANDARD_PATCH_SIZE
,
STANDARD_PATCH_SIZE
);
Mat_
<
uchar
>
standardPatch
(
STANDARD_PATCH_SIZE
,
STANDARD_PATCH_SIZE
);
double
originalVariance
=
tldModel
->
getOriginalVariance
();
;
double
originalVariance
=
tldModel
->
getOriginalVariance
();
double
tmp
;
double
tmp
;
Mat
resized_img
,
blurred_img
;
Mat
resized_img
,
blurred_img
;
double
scale
=
SCALE_STEP
;
double
scale
=
SCALE_STEP
;
//double scale = SCALE_STEP * SCALE_STEP * SCALE_STEP * SCALE_STEP;
//double scale = SCALE_STEP * SCALE_STEP * SCALE_STEP * SCALE_STEP;
Size2d
size
(
img_
.
cols
/
scale
,
img_
.
rows
/
scale
);
Size2d
size
(
img_
.
cols
/
scale
,
img_
.
rows
/
scale
);
resize
(
img_
,
resized_img
,
size
);
resize
(
img_
,
resized_img
,
size
);
resize
(
imgBlurred_
,
blurred_img
,
size
);
resize
(
imgBlurred_
,
blurred_img
,
size
);
Mat_
<
double
>
intImgP
,
intImgP2
;
Mat_
<
double
>
intImgP
,
intImgP2
;
detector_
->
computeIntegralImages
(
resized_img
,
intImgP
,
intImgP2
);
detector_
->
computeIntegralImages
(
resized_img
,
intImgP
,
intImgP2
);
int
dx
=
initSize
.
width
/
10
,
dy
=
initSize
.
height
/
10
,
int
dx
=
initSize
.
width
/
10
,
dy
=
initSize
.
height
/
10
,
i
=
(
int
)(
x
/
scale
/
dx
),
j
=
(
int
)(
y
/
scale
/
dy
);
i
=
(
int
)(
x
/
scale
/
dx
),
j
=
(
int
)(
y
/
scale
/
dy
);
dfprintf
((
stderr
,
"patchVariance = %s
\n
"
,(
detector_
->
patchVariance
(
intImgP
,
intImgP2
,
originalVariance
,
dfprintf
((
stderr
,
"patchVariance = %s
\n
"
,
(
detector_
->
patchVariance
(
intImgP
,
intImgP2
,
originalVariance
,
Point
(
dx
*
i
,
dy
*
j
),
initSize
))
?
"true"
:
"false"
));
Point
(
dx
*
i
,
dy
*
j
),
initSize
))
?
"true"
:
"false"
));
tldModel
->
prepareClassifiers
((
int
)
blurred_img
.
step
[
0
]);
tldModel
->
prepareClassifiers
((
int
)
blurred_img
.
step
[
0
]);
dfprintf
((
stderr
,
"p = %f
\n
"
,(
tldModel
->
ensembleClassifierNum
(
&
blurred_img
.
at
<
uchar
>
(
dy
*
j
,
dx
*
i
)))));
dfprintf
((
stderr
,
"p = %f
\n
"
,
(
tldModel
->
ensembleClassifierNum
(
&
blurred_img
.
at
<
uchar
>
(
dy
*
j
,
dx
*
i
)))));
fprintf
(
stderr
,
"ensembleClassifier = %s
\n
"
,
fprintf
(
stderr
,
"ensembleClassifier = %s
\n
"
,
(
!
(
tldModel
->
ensembleClassifierNum
(
&
blurred_img
.
at
<
uchar
>
(
dy
*
j
,
dx
*
i
))
>
ENSEMBLE_THRESHOLD
))
?
"true"
:
"false"
);
(
!
(
tldModel
->
ensembleClassifierNum
(
&
blurred_img
.
at
<
uchar
>
(
dy
*
j
,
dx
*
i
))
>
ENSEMBLE_THRESHOLD
))
?
"true"
:
"false"
);
resample
(
resized_img
,
Rect2d
(
Point
(
dx
*
i
,
dy
*
j
),
initSize
),
standardPatch
);
resample
(
resized_img
,
Rect2d
(
Point
(
dx
*
i
,
dy
*
j
),
initSize
),
standardPatch
);
tmp
=
tldModel
->
Sr
(
standardPatch
);
tmp
=
tldModel
->
Sr
(
standardPatch
);
dfprintf
((
stderr
,
"Sr = %f
\n
"
,
tmp
));
dfprintf
((
stderr
,
"Sr = %f
\n
"
,
tmp
));
dfprintf
((
stderr
,
"isObject = %s
\n
"
,
(
tmp
>
THETA_NN
)
?
"true"
:
"false"
));
dfprintf
((
stderr
,
"isObject = %s
\n
"
,
(
tmp
>
THETA_NN
)
?
"true"
:
"false"
));
dfprintf
((
stderr
,
"shouldBeIntegrated = %s
\n
"
,
(
abs
(
tmp
-
THETA_NN
)
<
0.1
)
?
"true"
:
"false"
));
dfprintf
((
stderr
,
"shouldBeIntegrated = %s
\n
"
,
(
abs
(
tmp
-
THETA_NN
)
<
0.1
)
?
"true"
:
"false"
));
dfprintf
((
stderr
,
"Sc = %f
\n
"
,
tldModel
->
Sc
(
standardPatch
)));
dfprintf
((
stderr
,
"Sc = %f
\n
"
,
tldModel
->
Sc
(
standardPatch
)));
rectangle
(
imgCanvas
,
Rect2d
(
Point2d
(
scale
*
dx
*
i
,
scale
*
dy
*
j
),
Size2d
(
initSize
.
width
*
scale
,
initSize
.
height
*
scale
)),
0
,
2
,
1
);
rectangle
(
imgCanvas
,
Rect2d
(
Point2d
(
scale
*
dx
*
i
,
scale
*
dy
*
j
),
Size2d
(
initSize
.
width
*
scale
,
initSize
.
height
*
scale
)),
0
,
2
,
1
);
imshow
(
"picker"
,
imgCanvas
);
imshow
(
"picker"
,
imgCanvas
);
waitKey
();
waitKey
();
}
}
}
}
...
@@ -903,7 +929,7 @@ void TrackerTLDModel::pushIntoModel(const Mat_<uchar>& example, bool positive)
...
@@ -903,7 +929,7 @@ void TrackerTLDModel::pushIntoModel(const Mat_<uchar>& example, bool positive)
}
}
else
else
{
{
int
index
=
rng
.
uniform
((
int
)
0
,(
int
)
proxyV
->
size
());
int
index
=
rng
.
uniform
((
int
)
0
,
(
int
)
proxyV
->
size
());
(
*
proxyV
)[
index
]
=
example
;
(
*
proxyV
)[
index
]
=
example
;
(
*
proxyT
)[
index
]
=
(
*
proxyN
);
(
*
proxyT
)[
index
]
=
(
*
proxyN
);
}
}
...
...
modules/tracking/src/tld_tracker.hpp
View file @
4e14e8c8
...
@@ -57,60 +57,67 @@ namespace cv {namespace tld
...
@@ -57,60 +57,67 @@ namespace cv {namespace tld
#define dfprintf(x)
#define dfprintf(x)
#define dprintf(x)
#define dprintf(x)
#endif
#endif
#define MEASURE_TIME(a) {\
#define MEASURE_TIME(a)\
clock_t start;float milisec = 0.0;\
{\
start = clock();{a} milisec = 1000.0 * (clock() - start) / CLOCKS_PER_SEC;\
clock_t start; float milisec = 0.0; \
dprintf(("%-90s took %f milis\n",#a,milisec)); }
start = clock(); {a} milisec = 1000.0 * (clock() - start) / CLOCKS_PER_SEC; \
#define HERE dprintf(("line %d\n",__LINE__));fflush(stderr);
dprintf(("%-90s took %f milis\n", #a, milisec));\
#define START_TICK(name) { clock_t start;double milisec = 0.0; start = clock();
}
#define END_TICK(name) milisec = 1000.0 * (clock() - start) / CLOCKS_PER_SEC;\
#define HERE dprintf(("line %d\n", __LINE__)); fflush(stderr);
dprintf(("%s took %f milis\n",name,milisec)); }
#define START_TICK(name)\
{ \
clock_t start; double milisec = 0.0; start = clock();
#define END_TICK(name) milisec = 1000.0 * (clock() - start) / CLOCKS_PER_SEC; \
dprintf(("%s took %f milis\n", name, milisec)); \
}
extern
Rect2d
etalon
;
extern
Rect2d
etalon
;
void
myassert
(
const
Mat
&
img
);
void
myassert
(
const
Mat
&
img
);
void
printPatch
(
const
Mat_
<
uchar
>&
standardPatch
);
void
printPatch
(
const
Mat_
<
uchar
>&
standardPatch
);
std
::
string
type2str
(
const
Mat
&
mat
);
std
::
string
type2str
(
const
Mat
&
mat
);
void
drawWithRects
(
const
Mat
&
img
,
std
::
vector
<
Rect2d
>&
blackOnes
,
Rect2d
whiteOne
=
Rect2d
(
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
));
void
drawWithRects
(
const
Mat
&
img
,
std
::
vector
<
Rect2d
>&
blackOnes
,
Rect2d
whiteOne
=
Rect2d
(
-
1.0
,
-
1.0
,
-
1.0
,
-
1.0
));
void
drawWithRects
(
const
Mat
&
img
,
std
::
vector
<
Rect2d
>&
blackOnes
,
std
::
vector
<
Rect2d
>&
whiteOnes
,
String
fileName
=
""
);
void
drawWithRects
(
const
Mat
&
img
,
std
::
vector
<
Rect2d
>&
blackOnes
,
std
::
vector
<
Rect2d
>&
whiteOnes
,
String
fileName
=
""
);
//aux functions and variables
//aux functions and variables
template
<
typename
T
>
inline
T
CLIP
(
T
x
,
T
a
,
T
b
){
return
std
::
min
(
std
::
max
(
x
,
a
),
b
);
}
template
<
typename
T
>
inline
T
CLIP
(
T
x
,
T
a
,
T
b
){
return
std
::
min
(
std
::
max
(
x
,
a
),
b
);
}
/** Computes overlap between the two given rectangles. Overlap is computed as ratio of rectangles' intersection to that
/** Computes overlap between the two given rectangles. Overlap is computed as ratio of rectangles' intersection to that
* of their union.*/
* of their union.*/
double
overlap
(
const
Rect2d
&
r1
,
const
Rect2d
&
r2
);
double
overlap
(
const
Rect2d
&
r1
,
const
Rect2d
&
r2
);
/** Resamples the area surrounded by r2 in img so it matches the size of samples, where it is written.*/
/** Resamples the area surrounded by r2 in img so it matches the size of samples, where it is written.*/
void
resample
(
const
Mat
&
img
,
const
RotatedRect
&
r2
,
Mat_
<
uchar
>&
samples
);
void
resample
(
const
Mat
&
img
,
const
RotatedRect
&
r2
,
Mat_
<
uchar
>&
samples
);
/** Specialization of resample() for rectangles without retation for better performance and simplicity.*/
/** Specialization of resample() for rectangles without retation for better performance and simplicity.*/
void
resample
(
const
Mat
&
img
,
const
Rect2d
&
r2
,
Mat_
<
uchar
>&
samples
);
void
resample
(
const
Mat
&
img
,
const
Rect2d
&
r2
,
Mat_
<
uchar
>&
samples
);
/** Computes the variance of single given image.*/
/** Computes the variance of single given image.*/
double
variance
(
const
Mat
&
img
);
double
variance
(
const
Mat
&
img
);
/** Computes normalized corellation coefficient between the two patches (they should be
/** Computes normalized corellation coefficient between the two patches (they should be
* of the same size).*/
* of the same size).*/
double
NCC
(
const
Mat_
<
uchar
>&
patch1
,
const
Mat_
<
uchar
>&
patch2
);
double
NCC
(
const
Mat_
<
uchar
>&
patch1
,
const
Mat_
<
uchar
>&
patch2
);
void
getClosestN
(
std
::
vector
<
Rect2d
>&
scanGrid
,
Rect2d
bBox
,
int
n
,
std
::
vector
<
Rect2d
>&
res
);
void
getClosestN
(
std
::
vector
<
Rect2d
>&
scanGrid
,
Rect2d
bBox
,
int
n
,
std
::
vector
<
Rect2d
>&
res
);
double
scaleAndBlur
(
const
Mat
&
originalImg
,
int
scale
,
Mat
&
scaledImg
,
Mat
&
blurredImg
,
Size
GaussBlurKernelSize
,
double
scaleStep
);
double
scaleAndBlur
(
const
Mat
&
originalImg
,
int
scale
,
Mat
&
scaledImg
,
Mat
&
blurredImg
,
Size
GaussBlurKernelSize
,
double
scaleStep
);
int
getMedian
(
const
std
::
vector
<
int
>&
values
,
int
size
=
-
1
);
int
getMedian
(
const
std
::
vector
<
int
>&
values
,
int
size
=
-
1
);
class
TLDEnsembleClassifier
{
class
TLDEnsembleClassifier
{
public
:
public
:
static
int
makeClassifiers
(
Size
size
,
int
measurePerClassifier
,
int
gridSize
,
std
::
vector
<
TLDEnsembleClassifier
>&
classifiers
);
static
int
makeClassifiers
(
Size
size
,
int
measurePerClassifier
,
int
gridSize
,
std
::
vector
<
TLDEnsembleClassifier
>&
classifiers
);
void
integrate
(
const
Mat_
<
uchar
>&
patch
,
bool
isPositive
);
void
integrate
(
const
Mat_
<
uchar
>&
patch
,
bool
isPositive
);
double
posteriorProbability
(
const
uchar
*
data
,
int
rowstep
)
const
;
double
posteriorProbability
(
const
uchar
*
data
,
int
rowstep
)
const
;
double
posteriorProbabilityFast
(
const
uchar
*
data
)
const
;
double
posteriorProbabilityFast
(
const
uchar
*
data
)
const
;
void
prepareClassifier
(
int
rowstep
);
void
prepareClassifier
(
int
rowstep
);
private
:
private
:
TLDEnsembleClassifier
(
const
std
::
vector
<
Vec4b
>&
meas
,
int
beg
,
int
end
);
TLDEnsembleClassifier
(
const
std
::
vector
<
Vec4b
>&
meas
,
int
beg
,
int
end
);
static
void
stepPrefSuff
(
std
::
vector
<
Vec4b
>
&
arr
,
int
pos
,
int
len
,
int
gridSize
);
static
void
stepPrefSuff
(
std
::
vector
<
Vec4b
>
&
arr
,
int
pos
,
int
len
,
int
gridSize
);
int
code
(
const
uchar
*
data
,
int
rowstep
)
const
;
int
code
(
const
uchar
*
data
,
int
rowstep
)
const
;
int
codeFast
(
const
uchar
*
data
)
const
;
int
codeFast
(
const
uchar
*
data
)
const
;
std
::
vector
<
Point2i
>
posAndNeg
;
std
::
vector
<
Point2i
>
posAndNeg
;
std
::
vector
<
Vec4b
>
measurements
;
std
::
vector
<
Vec4b
>
measurements
;
std
::
vector
<
Point2i
>
offset
;
std
::
vector
<
Point2i
>
offset
;
int
lastStep_
;
int
lastStep_
;
};
};
class
TrackerProxy
{
class
TrackerProxy
{
public
:
public
:
virtual
bool
init
(
const
Mat
&
image
,
const
Rect2d
&
boundingBox
)
=
0
;
virtual
bool
init
(
const
Mat
&
image
,
const
Rect2d
&
boundingBox
)
=
0
;
virtual
bool
update
(
const
Mat
&
image
,
Rect2d
&
boundingBox
)
=
0
;
virtual
bool
update
(
const
Mat
&
image
,
Rect2d
&
boundingBox
)
=
0
;
virtual
~
TrackerProxy
(){}
virtual
~
TrackerProxy
(){}
};
};
...
...
modules/tracking/src/tld_utils.cpp
View file @
4e14e8c8
...
@@ -53,58 +53,61 @@ namespace cv {namespace tld
...
@@ -53,58 +53,61 @@ namespace cv {namespace tld
{
{
//debug functions and variables
//debug functions and variables
Rect2d
etalon
(
14.0
,
110.0
,
20.0
,
20.0
);
Rect2d
etalon
(
14.0
,
110.0
,
20.0
,
20.0
);
void
drawWithRects
(
const
Mat
&
img
,
std
::
vector
<
Rect2d
>&
blackOnes
,
Rect2d
whiteOne
){
void
drawWithRects
(
const
Mat
&
img
,
std
::
vector
<
Rect2d
>&
blackOnes
,
Rect2d
whiteOne
)
{
Mat
image
;
Mat
image
;
img
.
copyTo
(
image
);
img
.
copyTo
(
image
);
if
(
whiteOne
.
width
>=
0
){
if
(
whiteOne
.
width
>=
0
)
rectangle
(
image
,
whiteOne
,
255
,
1
,
1
);
rectangle
(
image
,
whiteOne
,
255
,
1
,
1
);
}
for
(
int
i
=
0
;
i
<
(
int
)
blackOnes
.
size
();
i
++
)
for
(
int
i
=
0
;
i
<
(
int
)
blackOnes
.
size
();
i
++
){
rectangle
(
image
,
blackOnes
[
i
],
0
,
1
,
1
);
rectangle
(
image
,
blackOnes
[
i
],
0
,
1
,
1
);
imshow
(
"img"
,
image
);
}
imshow
(
"img"
,
image
);
}
}
void
drawWithRects
(
const
Mat
&
img
,
std
::
vector
<
Rect2d
>&
blackOnes
,
std
::
vector
<
Rect2d
>&
whiteOnes
,
String
filename
){
void
drawWithRects
(
const
Mat
&
img
,
std
::
vector
<
Rect2d
>&
blackOnes
,
std
::
vector
<
Rect2d
>&
whiteOnes
,
String
filename
)
{
Mat
image
;
Mat
image
;
static
int
frameCounter
=
1
;
static
int
frameCounter
=
1
;
img
.
copyTo
(
image
);
img
.
copyTo
(
image
);
for
(
int
i
=
0
;
i
<
(
int
)
whiteOnes
.
size
();
i
++
){
for
(
int
i
=
0
;
i
<
(
int
)
whiteOnes
.
size
();
i
++
)
rectangle
(
image
,
whiteOnes
[
i
],
255
,
1
,
1
);
rectangle
(
image
,
whiteOnes
[
i
],
255
,
1
,
1
);
}
for
(
int
i
=
0
;
i
<
(
int
)
blackOnes
.
size
();
i
++
)
for
(
int
i
=
0
;
i
<
(
int
)
blackOnes
.
size
();
i
++
){
rectangle
(
image
,
blackOnes
[
i
],
0
,
1
,
1
);
rectangle
(
image
,
blackOnes
[
i
],
0
,
1
,
1
);
imshow
(
"img"
,
image
);
}
if
(
filename
.
length
()
>
0
)
imshow
(
"img"
,
image
);
{
if
(
filename
.
length
()
>
0
){
char
inbuf
[
100
];
char
inbuf
[
100
];
sprintf
(
inbuf
,
"%s%d.jpg"
,
filename
.
c_str
(),
frameCounter
);
sprintf
(
inbuf
,
"%s%d.jpg"
,
filename
.
c_str
(),
frameCounter
);
imwrite
(
inbuf
,
image
);
imwrite
(
inbuf
,
image
);
frameCounter
++
;
frameCounter
++
;
}
}
}
}
void
myassert
(
const
Mat
&
img
){
void
myassert
(
const
Mat
&
img
)
{
int
count
=
0
;
int
count
=
0
;
for
(
int
i
=
0
;
i
<
img
.
rows
;
i
++
){
for
(
int
i
=
0
;
i
<
img
.
rows
;
i
++
)
for
(
int
j
=
0
;
j
<
img
.
cols
;
j
++
){
{
if
(
img
.
at
<
uchar
>
(
i
,
j
)
==
0
){
for
(
int
j
=
0
;
j
<
img
.
cols
;
j
++
)
{
if
(
img
.
at
<
uchar
>
(
i
,
j
)
==
0
)
count
++
;
count
++
;
}
}
}
}
}
dprintf
((
"black: %d out of %d (%f)
\n
"
,
count
,
img
.
rows
*
img
.
cols
,
1.0
*
count
/
img
.
rows
/
img
.
cols
));
dprintf
((
"black: %d out of %d (%f)
\n
"
,
count
,
img
.
rows
*
img
.
cols
,
1.0
*
count
/
img
.
rows
/
img
.
cols
));
}
}
void
printPatch
(
const
Mat_
<
uchar
>&
standardPatch
){
void
printPatch
(
const
Mat_
<
uchar
>&
standardPatch
)
for
(
int
i
=
0
;
i
<
standardPatch
.
rows
;
i
++
){
{
for
(
int
j
=
0
;
j
<
standardPatch
.
cols
;
j
++
){
for
(
int
i
=
0
;
i
<
standardPatch
.
rows
;
i
++
)
dprintf
((
"%5.2f, "
,(
double
)
standardPatch
(
i
,
j
)));
{
}
for
(
int
j
=
0
;
j
<
standardPatch
.
cols
;
j
++
)
dprintf
((
"%5.2f, "
,
(
double
)
standardPatch
(
i
,
j
)));
dprintf
((
"
\n
"
));
dprintf
((
"
\n
"
));
}
}
}
}
std
::
string
type2str
(
const
Mat
&
mat
){
std
::
string
type2str
(
const
Mat
&
mat
)
{
int
type
=
mat
.
type
();
int
type
=
mat
.
type
();
std
::
string
r
;
std
::
string
r
;
...
@@ -129,59 +132,63 @@ std::string type2str(const Mat& mat){
...
@@ -129,59 +132,63 @@ std::string type2str(const Mat& mat){
}
}
//generic functions
//generic functions
double
scaleAndBlur
(
const
Mat
&
originalImg
,
int
scale
,
Mat
&
scaledImg
,
Mat
&
blurredImg
,
Size
GaussBlurKernelSize
,
double
scaleStep
){
double
scaleAndBlur
(
const
Mat
&
originalImg
,
int
scale
,
Mat
&
scaledImg
,
Mat
&
blurredImg
,
Size
GaussBlurKernelSize
,
double
scaleStep
)
{
double
dScale
=
1.0
;
double
dScale
=
1.0
;
for
(
int
i
=
0
;
i
<
scale
;
i
++
,
dScale
*=
scaleStep
);
for
(
int
i
=
0
;
i
<
scale
;
i
++
,
dScale
*=
scaleStep
);
Size2d
size
=
originalImg
.
size
();
Size2d
size
=
originalImg
.
size
();
size
.
height
/=
dScale
;
size
.
width
/=
dScale
;
size
.
height
/=
dScale
;
size
.
width
/=
dScale
;
resize
(
originalImg
,
scaledImg
,
size
);
resize
(
originalImg
,
scaledImg
,
size
);
GaussianBlur
(
scaledImg
,
blurredImg
,
GaussBlurKernelSize
,
0.0
);
GaussianBlur
(
scaledImg
,
blurredImg
,
GaussBlurKernelSize
,
0.0
);
return
dScale
;
return
dScale
;
}
}
void
getClosestN
(
std
::
vector
<
Rect2d
>&
scanGrid
,
Rect2d
bBox
,
int
n
,
std
::
vector
<
Rect2d
>&
res
){
void
getClosestN
(
std
::
vector
<
Rect2d
>&
scanGrid
,
Rect2d
bBox
,
int
n
,
std
::
vector
<
Rect2d
>&
res
)
if
(
n
>=
(
int
)
scanGrid
.
size
()){
{
res
.
assign
(
scanGrid
.
begin
(),
scanGrid
.
end
());
if
(
n
>=
(
int
)
scanGrid
.
size
()
)
{
res
.
assign
(
scanGrid
.
begin
(),
scanGrid
.
end
());
return
;
return
;
}
}
std
::
vector
<
double
>
overlaps
;
std
::
vector
<
double
>
overlaps
;
overlaps
.
assign
(
n
,
0.0
);
overlaps
.
assign
(
n
,
0.0
);
res
.
assign
(
scanGrid
.
begin
(),
scanGrid
.
begin
()
+
n
);
res
.
assign
(
scanGrid
.
begin
(),
scanGrid
.
begin
()
+
n
);
for
(
int
i
=
0
;
i
<
n
;
i
++
){
for
(
int
i
=
0
;
i
<
n
;
i
++
)
overlaps
[
i
]
=
overlap
(
res
[
i
],
bBox
);
overlaps
[
i
]
=
overlap
(
res
[
i
],
bBox
);
}
double
otmp
;
double
otmp
;
Rect2d
rtmp
;
Rect2d
rtmp
;
for
(
int
i
=
1
;
i
<
n
;
i
++
){
for
(
int
i
=
1
;
i
<
n
;
i
++
)
{
int
j
=
i
;
int
j
=
i
;
while
(
j
>
0
&&
overlaps
[
j
-
1
]
>
overlaps
[
j
])
{
while
(
j
>
0
&&
overlaps
[
j
-
1
]
>
overlaps
[
j
])
{
otmp
=
overlaps
[
j
];
overlaps
[
j
]
=
overlaps
[
j
-
1
];
overlaps
[
j
-
1
]
=
otmp
;
otmp
=
overlaps
[
j
];
overlaps
[
j
]
=
overlaps
[
j
-
1
];
overlaps
[
j
-
1
]
=
otmp
;
rtmp
=
res
[
j
];
res
[
j
]
=
res
[
j
-
1
];
res
[
j
-
1
]
=
rtmp
;
rtmp
=
res
[
j
];
res
[
j
]
=
res
[
j
-
1
];
res
[
j
-
1
]
=
rtmp
;
j
--
;
j
--
;
}
}
}
}
for
(
int
i
=
n
;
i
<
(
int
)
scanGrid
.
size
();
i
++
){
for
(
int
i
=
n
;
i
<
(
int
)
scanGrid
.
size
();
i
++
)
{
double
o
=
0.0
;
double
o
=
0.0
;
if
(
(
o
=
overlap
(
scanGrid
[
i
],
bBox
))
<=
overlaps
[
0
]){
if
(
(
o
=
overlap
(
scanGrid
[
i
],
bBox
))
<=
overlaps
[
0
]
)
continue
;
continue
;
}
int
j
=
0
;
int
j
=
0
;
while
(
j
<
n
&&
overlaps
[
j
]
<
o
)
while
(
j
<
n
&&
overlaps
[
j
]
<
o
)
{
j
++
;
j
++
;
}
j
--
;
j
--
;
for
(
int
k
=
0
;
k
<
j
;
overlaps
[
k
]
=
overlaps
[
k
+
1
],
res
[
k
]
=
res
[
k
+
1
],
k
++
);
for
(
int
k
=
0
;
k
<
j
;
overlaps
[
k
]
=
overlaps
[
k
+
1
],
res
[
k
]
=
res
[
k
+
1
],
k
++
);
overlaps
[
j
]
=
o
;
res
[
j
]
=
scanGrid
[
i
];
overlaps
[
j
]
=
o
;
res
[
j
]
=
scanGrid
[
i
];
}
}
}
}
double
variance
(
const
Mat
&
img
){
double
variance
(
const
Mat
&
img
)
double
p
=
0
,
p2
=
0
;
{
for
(
int
i
=
0
;
i
<
img
.
rows
;
i
++
){
double
p
=
0
,
p2
=
0
;
for
(
int
j
=
0
;
j
<
img
.
cols
;
j
++
){
for
(
int
i
=
0
;
i
<
img
.
rows
;
i
++
)
p
+=
img
.
at
<
uchar
>
(
i
,
j
);
{
p2
+=
img
.
at
<
uchar
>
(
i
,
j
)
*
img
.
at
<
uchar
>
(
i
,
j
);
for
(
int
j
=
0
;
j
<
img
.
cols
;
j
++
)
{
p
+=
img
.
at
<
uchar
>
(
i
,
j
);
p2
+=
img
.
at
<
uchar
>
(
i
,
j
)
*
img
.
at
<
uchar
>
(
i
,
j
);
}
}
}
}
p
/=
(
img
.
cols
*
img
.
rows
);
p
/=
(
img
.
cols
*
img
.
rows
);
...
@@ -189,87 +196,96 @@ double variance(const Mat& img){
...
@@ -189,87 +196,96 @@ double variance(const Mat& img){
return
p2
-
p
*
p
;
return
p2
-
p
*
p
;
}
}
double
NCC
(
const
Mat_
<
uchar
>&
patch1
,
const
Mat_
<
uchar
>&
patch2
){
double
NCC
(
const
Mat_
<
uchar
>&
patch1
,
const
Mat_
<
uchar
>&
patch2
)
CV_Assert
(
patch1
.
rows
==
patch2
.
rows
);
{
CV_Assert
(
patch1
.
cols
==
patch2
.
cols
);
CV_Assert
(
patch1
.
rows
==
patch2
.
rows
);
CV_Assert
(
patch1
.
cols
==
patch2
.
cols
);
int
N
=
patch1
.
rows
*
patch1
.
cols
;
int
N
=
patch1
.
rows
*
patch1
.
cols
;
int
s1
=
0
,
s2
=
0
,
n1
=
0
,
n2
=
0
,
prod
=
0
;
int
s1
=
0
,
s2
=
0
,
n1
=
0
,
n2
=
0
,
prod
=
0
;
for
(
int
i
=
0
;
i
<
patch1
.
rows
;
i
++
){
for
(
int
i
=
0
;
i
<
patch1
.
rows
;
i
++
)
for
(
int
j
=
0
;
j
<
patch1
.
cols
;
j
++
){
{
int
p1
=
patch1
(
i
,
j
),
p2
=
patch2
(
i
,
j
);
for
(
int
j
=
0
;
j
<
patch1
.
cols
;
j
++
)
{
int
p1
=
patch1
(
i
,
j
),
p2
=
patch2
(
i
,
j
);
s1
+=
p1
;
s2
+=
p2
;
s1
+=
p1
;
s2
+=
p2
;
n1
+=
(
p1
*
p1
);
n2
+=
(
p2
*
p2
);
n1
+=
(
p1
*
p1
);
n2
+=
(
p2
*
p2
);
prod
+=
(
p1
*
p2
);
prod
+=
(
p1
*
p2
);
}
}
}
}
double
sq1
=
sqrt
(
std
::
max
(
0.0
,
n1
-
1.0
*
s1
*
s1
/
N
)),
sq2
=
sqrt
(
std
::
max
(
0.0
,
n2
-
1.0
*
s2
*
s2
/
N
));
double
sq1
=
sqrt
(
std
::
max
(
0.0
,
n1
-
1.0
*
s1
*
s1
/
N
)),
sq2
=
sqrt
(
std
::
max
(
0.0
,
n2
-
1.0
*
s2
*
s2
/
N
));
double
ares
=
(
sq2
==
0
)
?
sq1
/
abs
(
sq1
)
:
(
prod
-
s1
*
s2
/
N
)
/
sq1
/
sq2
;
double
ares
=
(
sq2
==
0
)
?
sq1
/
abs
(
sq1
)
:
(
prod
-
s1
*
s2
/
N
)
/
sq1
/
sq2
;
return
ares
;
return
ares
;
}
}
int
getMedian
(
const
std
::
vector
<
int
>&
values
,
int
size
){
int
getMedian
(
const
std
::
vector
<
int
>&
values
,
int
size
)
if
(
size
==
-
1
){
{
if
(
size
==
-
1
)
size
=
(
int
)
values
.
size
();
size
=
(
int
)
values
.
size
();
}
std
::
vector
<
int
>
copy
(
values
.
begin
(),
values
.
begin
()
+
size
);
std
::
vector
<
int
>
copy
(
values
.
begin
(),
values
.
begin
()
+
size
);
std
::
sort
(
copy
.
begin
(),
copy
.
end
());
std
::
sort
(
copy
.
begin
(),
copy
.
end
());
if
(
size
%
2
==
0
)
if
(
size
%
2
==
0
){
return
(
copy
[
size
/
2
-
1
]
+
copy
[
size
/
2
])
/
2
;
return
(
copy
[
size
/
2
-
1
]
+
copy
[
size
/
2
])
/
2
;
}
else
{
else
return
copy
[(
size
-
1
)
/
2
];
return
copy
[(
size
-
1
)
/
2
];
}
}
}
double
overlap
(
const
Rect2d
&
r1
,
const
Rect2d
&
r2
){
double
overlap
(
const
Rect2d
&
r1
,
const
Rect2d
&
r2
)
{
double
a1
=
r1
.
area
(),
a2
=
r2
.
area
(),
a0
=
(
r1
&
r2
).
area
();
double
a1
=
r1
.
area
(),
a2
=
r2
.
area
(),
a0
=
(
r1
&
r2
).
area
();
return
a0
/
(
a1
+
a2
-
a0
);
return
a0
/
(
a1
+
a2
-
a0
);
}
}
void
resample
(
const
Mat
&
img
,
const
RotatedRect
&
r2
,
Mat_
<
uchar
>&
samples
){
void
resample
(
const
Mat
&
img
,
const
RotatedRect
&
r2
,
Mat_
<
uchar
>&
samples
)
Mat_
<
float
>
M
(
2
,
3
),
R
(
2
,
2
),
Si
(
2
,
2
),
s
(
2
,
1
),
o
(
2
,
1
);
{
R
(
0
,
0
)
=
(
float
)
cos
(
r2
.
angle
*
CV_PI
/
180
);
R
(
0
,
1
)
=
(
float
)(
-
sin
(
r2
.
angle
*
CV_PI
/
180
));
Mat_
<
float
>
M
(
2
,
3
),
R
(
2
,
2
),
Si
(
2
,
2
),
s
(
2
,
1
),
o
(
2
,
1
);
R
(
1
,
0
)
=
(
float
)
sin
(
r2
.
angle
*
CV_PI
/
180
);
R
(
1
,
1
)
=
(
float
)
cos
(
r2
.
angle
*
CV_PI
/
180
);
R
(
0
,
0
)
=
(
float
)
cos
(
r2
.
angle
*
CV_PI
/
180
);
R
(
0
,
1
)
=
(
float
)(
-
sin
(
r2
.
angle
*
CV_PI
/
180
));
Si
(
0
,
0
)
=
(
float
)(
samples
.
cols
/
r2
.
size
.
width
);
Si
(
0
,
1
)
=
0.0
f
;
R
(
1
,
0
)
=
(
float
)
sin
(
r2
.
angle
*
CV_PI
/
180
);
R
(
1
,
1
)
=
(
float
)
cos
(
r2
.
angle
*
CV_PI
/
180
);
Si
(
1
,
0
)
=
0.0
f
;
Si
(
1
,
1
)
=
(
float
)(
samples
.
rows
/
r2
.
size
.
height
);
Si
(
0
,
0
)
=
(
float
)(
samples
.
cols
/
r2
.
size
.
width
);
Si
(
0
,
1
)
=
0.0
f
;
s
(
0
,
0
)
=
(
float
)
samples
.
cols
;
s
(
1
,
0
)
=
(
float
)
samples
.
rows
;
Si
(
1
,
0
)
=
0.0
f
;
Si
(
1
,
1
)
=
(
float
)(
samples
.
rows
/
r2
.
size
.
height
);
o
(
0
,
0
)
=
r2
.
center
.
x
;
o
(
1
,
0
)
=
r2
.
center
.
y
;
s
(
0
,
0
)
=
(
float
)
samples
.
cols
;
s
(
1
,
0
)
=
(
float
)
samples
.
rows
;
Mat_
<
float
>
A
(
2
,
2
),
b
(
2
,
1
);
o
(
0
,
0
)
=
r2
.
center
.
x
;
o
(
1
,
0
)
=
r2
.
center
.
y
;
Mat_
<
float
>
A
(
2
,
2
),
b
(
2
,
1
);
A
=
Si
*
R
;
A
=
Si
*
R
;
b
=
s
/
2.0
-
Si
*
R
*
o
;
b
=
s
/
2.0
-
Si
*
R
*
o
;
A
.
copyTo
(
M
.
colRange
(
Range
(
0
,
2
)));
A
.
copyTo
(
M
.
colRange
(
Range
(
0
,
2
)));
b
.
copyTo
(
M
.
colRange
(
Range
(
2
,
3
)));
b
.
copyTo
(
M
.
colRange
(
Range
(
2
,
3
)));
warpAffine
(
img
,
samples
,
M
,
samples
.
size
());
warpAffine
(
img
,
samples
,
M
,
samples
.
size
());
}
}
void
resample
(
const
Mat
&
img
,
const
Rect2d
&
r2
,
Mat_
<
uchar
>&
samples
){
void
resample
(
const
Mat
&
img
,
const
Rect2d
&
r2
,
Mat_
<
uchar
>&
samples
)
Mat_
<
float
>
M
(
2
,
3
);
{
M
(
0
,
0
)
=
(
float
)(
samples
.
cols
/
r2
.
width
);
M
(
0
,
1
)
=
0.0
f
;
M
(
0
,
2
)
=
(
float
)(
-
r2
.
x
*
samples
.
cols
/
r2
.
width
);
Mat_
<
float
>
M
(
2
,
3
);
M
(
1
,
0
)
=
0.0
f
;
M
(
1
,
1
)
=
(
float
)(
samples
.
rows
/
r2
.
height
);
M
(
1
,
2
)
=
(
float
)(
-
r2
.
y
*
samples
.
rows
/
r2
.
height
);
M
(
0
,
0
)
=
(
float
)(
samples
.
cols
/
r2
.
width
);
M
(
0
,
1
)
=
0.0
f
;
M
(
0
,
2
)
=
(
float
)(
-
r2
.
x
*
samples
.
cols
/
r2
.
width
);
warpAffine
(
img
,
samples
,
M
,
samples
.
size
());
M
(
1
,
0
)
=
0.0
f
;
M
(
1
,
1
)
=
(
float
)(
samples
.
rows
/
r2
.
height
);
M
(
1
,
2
)
=
(
float
)(
-
r2
.
y
*
samples
.
rows
/
r2
.
height
);
warpAffine
(
img
,
samples
,
M
,
samples
.
size
());
}
}
//other stuff
//other stuff
void
TLDEnsembleClassifier
::
stepPrefSuff
(
std
::
vector
<
Vec4b
>&
arr
,
int
pos
,
int
len
,
int
gridSize
){
void
TLDEnsembleClassifier
::
stepPrefSuff
(
std
::
vector
<
Vec4b
>&
arr
,
int
pos
,
int
len
,
int
gridSize
)
{
#if 0
#if 0
int step = len / (gridSize - 1), pref = (len - step * (gridSize - 1)) / 2;
int step = len / (gridSize - 1), pref = (len - step * (gridSize - 1)) / 2;
for(
int i = 0;i < (int)(sizeof(x1) / sizeof(x1[0]));i++){
for(
int i = 0; i < (int)(sizeof(x1) / sizeof(x1[0])); i++ )
arr[i] = pref + arr[i] * step;
arr[i] = pref + arr[i] * step;
}
#else
#else
int
total
=
len
-
gridSize
;
int
total
=
len
-
gridSize
;
int
quo
=
total
/
(
gridSize
-
1
),
rem
=
total
%
(
gridSize
-
1
);
int
quo
=
total
/
(
gridSize
-
1
),
rem
=
total
%
(
gridSize
-
1
);
int
smallStep
=
quo
,
bigStep
=
quo
+
1
;
int
smallStep
=
quo
,
bigStep
=
quo
+
1
;
int
bigOnes
=
rem
,
smallOnes
=
gridSize
-
bigOnes
-
1
;
int
bigOnes
=
rem
,
smallOnes
=
gridSize
-
bigOnes
-
1
;
int
bigOnes_front
=
bigOnes
/
2
,
bigOnes_back
=
bigOnes
-
bigOnes_front
;
int
bigOnes_front
=
bigOnes
/
2
,
bigOnes_back
=
bigOnes
-
bigOnes_front
;
for
(
int
i
=
0
;
i
<
(
int
)
arr
.
size
();
i
++
){
for
(
int
i
=
0
;
i
<
(
int
)
arr
.
size
();
i
++
)
if
(
arr
[
i
].
val
[
pos
]
<
bigOnes_back
){
{
if
(
arr
[
i
].
val
[
pos
]
<
bigOnes_back
)
{
arr
[
i
].
val
[
pos
]
=
(
uchar
)(
arr
[
i
].
val
[
pos
]
*
bigStep
+
arr
[
i
].
val
[
pos
]);
arr
[
i
].
val
[
pos
]
=
(
uchar
)(
arr
[
i
].
val
[
pos
]
*
bigStep
+
arr
[
i
].
val
[
pos
]);
continue
;
continue
;
}
}
if
(
arr
[
i
].
val
[
pos
]
<
(
bigOnes_front
+
smallOnes
)){
if
(
arr
[
i
].
val
[
pos
]
<
(
bigOnes_front
+
smallOnes
)
)
{
arr
[
i
].
val
[
pos
]
=
(
uchar
)(
bigOnes_front
*
bigStep
+
(
arr
[
i
].
val
[
pos
]
-
bigOnes_front
)
*
smallStep
+
arr
[
i
].
val
[
pos
]);
arr
[
i
].
val
[
pos
]
=
(
uchar
)(
bigOnes_front
*
bigStep
+
(
arr
[
i
].
val
[
pos
]
-
bigOnes_front
)
*
smallStep
+
arr
[
i
].
val
[
pos
]);
continue
;
continue
;
}
}
if
(
arr
[
i
].
val
[
pos
]
<
(
bigOnes_front
+
smallOnes
+
bigOnes_back
)){
if
(
arr
[
i
].
val
[
pos
]
<
(
bigOnes_front
+
smallOnes
+
bigOnes_back
)
)
{
arr
[
i
].
val
[
pos
]
=
arr
[
i
].
val
[
pos
]
=
(
uchar
)(
bigOnes_front
*
bigStep
+
smallOnes
*
smallStep
+
(
uchar
)(
bigOnes_front
*
bigStep
+
smallOnes
*
smallStep
+
(
arr
[
i
].
val
[
pos
]
-
(
bigOnes_front
+
smallOnes
))
*
bigStep
+
arr
[
i
].
val
[
pos
]);
(
arr
[
i
].
val
[
pos
]
-
(
bigOnes_front
+
smallOnes
))
*
bigStep
+
arr
[
i
].
val
[
pos
]);
...
@@ -279,62 +295,69 @@ void TLDEnsembleClassifier::stepPrefSuff(std::vector<Vec4b>& arr,int pos,int len
...
@@ -279,62 +295,69 @@ void TLDEnsembleClassifier::stepPrefSuff(std::vector<Vec4b>& arr,int pos,int len
}
}
#endif
#endif
}
}
void
TLDEnsembleClassifier
::
prepareClassifier
(
int
rowstep
){
void
TLDEnsembleClassifier
::
prepareClassifier
(
int
rowstep
)
if
(
lastStep_
!=
rowstep
){
{
if
(
lastStep_
!=
rowstep
)
{
lastStep_
=
rowstep
;
lastStep_
=
rowstep
;
for
(
int
i
=
0
;
i
<
(
int
)
offset
.
size
();
i
++
){
for
(
int
i
=
0
;
i
<
(
int
)
offset
.
size
();
i
++
)
{
offset
[
i
].
x
=
rowstep
*
measurements
[
i
].
val
[
0
]
+
measurements
[
i
].
val
[
1
];
offset
[
i
].
x
=
rowstep
*
measurements
[
i
].
val
[
0
]
+
measurements
[
i
].
val
[
1
];
offset
[
i
].
y
=
rowstep
*
measurements
[
i
].
val
[
2
]
+
measurements
[
i
].
val
[
3
];
offset
[
i
].
y
=
rowstep
*
measurements
[
i
].
val
[
2
]
+
measurements
[
i
].
val
[
3
];
}
}
}
}
}
}
TLDEnsembleClassifier
::
TLDEnsembleClassifier
(
const
std
::
vector
<
Vec4b
>&
meas
,
int
beg
,
int
end
)
:
lastStep_
(
-
1
){
TLDEnsembleClassifier
::
TLDEnsembleClassifier
(
const
std
::
vector
<
Vec4b
>&
meas
,
int
beg
,
int
end
)
:
lastStep_
(
-
1
)
{
int
posSize
=
1
,
mpc
=
end
-
beg
;
int
posSize
=
1
,
mpc
=
end
-
beg
;
for
(
int
i
=
0
;
i
<
mpc
;
i
++
)
for
(
int
i
=
0
;
i
<
mpc
;
i
++
)
posSize
*=
2
;
posSize
*=
2
;
posAndNeg
.
assign
(
posSize
,
Point2i
(
0
,
0
));
posAndNeg
.
assign
(
posSize
,
Point2i
(
0
,
0
));
measurements
.
assign
(
meas
.
begin
()
+
beg
,
meas
.
begin
()
+
end
);
measurements
.
assign
(
meas
.
begin
()
+
beg
,
meas
.
begin
()
+
end
);
offset
.
assign
(
mpc
,
Point2i
(
0
,
0
));
offset
.
assign
(
mpc
,
Point2i
(
0
,
0
));
}
}
void
TLDEnsembleClassifier
::
integrate
(
const
Mat_
<
uchar
>&
patch
,
bool
isPositive
){
void
TLDEnsembleClassifier
::
integrate
(
const
Mat_
<
uchar
>&
patch
,
bool
isPositive
)
int
position
=
code
(
patch
.
data
,(
int
)
patch
.
step
[
0
]);
{
if
(
isPositive
){
int
position
=
code
(
patch
.
data
,
(
int
)
patch
.
step
[
0
]);
if
(
isPositive
)
posAndNeg
[
position
].
x
++
;
posAndNeg
[
position
].
x
++
;
}
else
{
else
posAndNeg
[
position
].
y
++
;
posAndNeg
[
position
].
y
++
;
}
}
}
double
TLDEnsembleClassifier
::
posteriorProbability
(
const
uchar
*
data
,
int
rowstep
)
const
{
double
TLDEnsembleClassifier
::
posteriorProbability
(
const
uchar
*
data
,
int
rowstep
)
const
int
position
=
code
(
data
,
rowstep
);
{
int
position
=
code
(
data
,
rowstep
);
double
posNum
=
(
double
)
posAndNeg
[
position
].
x
,
negNum
=
(
double
)
posAndNeg
[
position
].
y
;
double
posNum
=
(
double
)
posAndNeg
[
position
].
x
,
negNum
=
(
double
)
posAndNeg
[
position
].
y
;
if
(
posNum
==
0.0
&&
negNum
==
0.0
){
if
(
posNum
==
0.0
&&
negNum
==
0.0
)
return
0.0
;
return
0.0
;
}
else
{
else
return
posNum
/
(
posNum
+
negNum
);
return
posNum
/
(
posNum
+
negNum
);
}
}
}
double
TLDEnsembleClassifier
::
posteriorProbabilityFast
(
const
uchar
*
data
)
const
{
double
TLDEnsembleClassifier
::
posteriorProbabilityFast
(
const
uchar
*
data
)
const
{
int
position
=
codeFast
(
data
);
int
position
=
codeFast
(
data
);
double
posNum
=
(
double
)
posAndNeg
[
position
].
x
,
negNum
=
(
double
)
posAndNeg
[
position
].
y
;
double
posNum
=
(
double
)
posAndNeg
[
position
].
x
,
negNum
=
(
double
)
posAndNeg
[
position
].
y
;
if
(
posNum
==
0.0
&&
negNum
==
0.0
){
if
(
posNum
==
0.0
&&
negNum
==
0.0
)
return
0.0
;
return
0.0
;
}
else
{
else
return
posNum
/
(
posNum
+
negNum
);
return
posNum
/
(
posNum
+
negNum
);
}
}
}
int
TLDEnsembleClassifier
::
codeFast
(
const
uchar
*
data
)
const
{
int
TLDEnsembleClassifier
::
codeFast
(
const
uchar
*
data
)
const
{
int
position
=
0
;
int
position
=
0
;
for
(
int
i
=
0
;
i
<
(
int
)
measurements
.
size
();
i
++
){
for
(
int
i
=
0
;
i
<
(
int
)
measurements
.
size
();
i
++
)
{
position
=
position
<<
1
;
position
=
position
<<
1
;
if
(
data
[
offset
[
i
].
x
]
<
data
[
offset
[
i
].
y
]){
if
(
data
[
offset
[
i
].
x
]
<
data
[
offset
[
i
].
y
]
)
position
++
;
position
++
;
}
}
}
return
position
;
return
position
;
}
}
int
TLDEnsembleClassifier
::
code
(
const
uchar
*
data
,
int
rowstep
)
const
{
int
TLDEnsembleClassifier
::
code
(
const
uchar
*
data
,
int
rowstep
)
const
{
int
position
=
0
;
int
position
=
0
;
for
(
int
i
=
0
;
i
<
(
int
)
measurements
.
size
();
i
++
){
for
(
int
i
=
0
;
i
<
(
int
)
measurements
.
size
();
i
++
)
{
position
=
position
<<
1
;
position
=
position
<<
1
;
if
(
*
(
data
+
rowstep
*
measurements
[
i
].
val
[
0
]
+
measurements
[
i
].
val
[
1
])
<
if
(
*
(
data
+
rowstep
*
measurements
[
i
].
val
[
0
]
+
measurements
[
i
].
val
[
1
])
<
*
(
data
+
rowstep
*
measurements
[
i
].
val
[
2
]
+
measurements
[
i
].
val
[
3
])
)
*
(
data
+
rowstep
*
measurements
[
i
].
val
[
2
]
+
measurements
[
i
].
val
[
3
])
)
...
@@ -344,34 +367,37 @@ int TLDEnsembleClassifier::code(const uchar* data,int rowstep)const{
...
@@ -344,34 +367,37 @@ int TLDEnsembleClassifier::code(const uchar* data,int rowstep)const{
}
}
return
position
;
return
position
;
}
}
int
TLDEnsembleClassifier
::
makeClassifiers
(
Size
size
,
int
measurePerClassifier
,
int
gridSize
,
int
TLDEnsembleClassifier
::
makeClassifiers
(
Size
size
,
int
measurePerClassifier
,
int
gridSize
,
std
::
vector
<
TLDEnsembleClassifier
>&
classifiers
){
std
::
vector
<
TLDEnsembleClassifier
>&
classifiers
)
{
std
::
vector
<
Vec4b
>
measurements
;
std
::
vector
<
Vec4b
>
measurements
;
for
(
int
i
=
0
;
i
<
gridSize
;
i
++
){
for
(
int
i
=
0
;
i
<
gridSize
;
i
++
)
for
(
int
j
=
0
;
j
<
gridSize
;
j
++
){
{
for
(
int
k
=
0
;
k
<
j
;
k
++
){
for
(
int
j
=
0
;
j
<
gridSize
;
j
++
)
{
for
(
int
k
=
0
;
k
<
j
;
k
++
)
{
Vec4b
m
;
Vec4b
m
;
m
.
val
[
0
]
=
m
.
val
[
2
]
=
i
;
m
.
val
[
0
]
=
m
.
val
[
2
]
=
i
;
m
.
val
[
1
]
=
j
;
m
.
val
[
3
]
=
k
;
m
.
val
[
1
]
=
j
;
m
.
val
[
3
]
=
k
;
measurements
.
push_back
(
m
);
measurements
.
push_back
(
m
);
m
.
val
[
1
]
=
m
.
val
[
3
]
=
i
;
m
.
val
[
1
]
=
m
.
val
[
3
]
=
i
;
m
.
val
[
0
]
=
j
;
m
.
val
[
2
]
=
k
;
m
.
val
[
0
]
=
j
;
m
.
val
[
2
]
=
k
;
measurements
.
push_back
(
m
);
measurements
.
push_back
(
m
);
}
}
}
}
}
}
random_shuffle
(
measurements
.
begin
(),
measurements
.
end
());
random_shuffle
(
measurements
.
begin
(),
measurements
.
end
());
stepPrefSuff
(
measurements
,
0
,
size
.
width
,
gridSize
);
stepPrefSuff
(
measurements
,
0
,
size
.
width
,
gridSize
);
stepPrefSuff
(
measurements
,
1
,
size
.
width
,
gridSize
);
stepPrefSuff
(
measurements
,
1
,
size
.
width
,
gridSize
);
stepPrefSuff
(
measurements
,
2
,
size
.
height
,
gridSize
);
stepPrefSuff
(
measurements
,
2
,
size
.
height
,
gridSize
);
stepPrefSuff
(
measurements
,
3
,
size
.
height
,
gridSize
);
stepPrefSuff
(
measurements
,
3
,
size
.
height
,
gridSize
);
for
(
int
i
=
0
,
howMany
=
measurements
.
size
()
/
measurePerClassifier
;
i
<
howMany
;
i
++
){
for
(
int
i
=
0
,
howMany
=
measurements
.
size
()
/
measurePerClassifier
;
i
<
howMany
;
i
++
)
classifiers
.
push_back
(
TLDEnsembleClassifier
(
measurements
,
i
*
measurePerClassifier
,
(
i
+
1
)
*
measurePerClassifier
));
classifiers
.
push_back
(
TLDEnsembleClassifier
(
measurements
,
i
*
measurePerClassifier
,
(
i
+
1
)
*
measurePerClassifier
));
}
return
(
int
)
classifiers
.
size
();
return
(
int
)
classifiers
.
size
();
}
}
...
...
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