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
489f8df9
Commit
489f8df9
authored
Oct 31, 2017
by
Vadim Pisarevsky
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1333 from sovrasov:tld_improvement
parents
6651fb0b
0c5a8e1f
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
244 additions
and
176 deletions
+244
-176
multiTracker.cpp
modules/tracking/src/multiTracker.cpp
+1
-1
tldDetector.cpp
modules/tracking/src/tldDetector.cpp
+54
-24
tldDetector.hpp
modules/tracking/src/tldDetector.hpp
+7
-1
tldModel.cpp
modules/tracking/src/tldModel.cpp
+11
-9
tldTracker.cpp
modules/tracking/src/tldTracker.cpp
+37
-34
tldTracker.hpp
modules/tracking/src/tldTracker.hpp
+1
-1
tldUtils.cpp
modules/tracking/src/tldUtils.cpp
+3
-43
tldUtils.hpp
modules/tracking/src/tldUtils.hpp
+0
-5
trackerMedianFlow.cpp
modules/tracking/src/trackerMedianFlow.cpp
+8
-52
tracking_utils.cpp
modules/tracking/src/tracking_utils.cpp
+69
-0
tracking_utils.hpp
modules/tracking/src/tracking_utils.hpp
+47
-0
test_trackers.cpp
modules/tracking/test/test_trackers.cpp
+6
-6
No files found.
modules/tracking/src/multiTracker.cpp
View file @
489f8df9
...
...
@@ -408,7 +408,7 @@ namespace cv
////To fix: Check the paper, probably this cause wrong learning
//
labPatch
.
isObject
=
srValue
>
tld
::
THETA_NN
;
labPatch
.
shouldBeIntegrated
=
abs
(
srValue
-
tld
::
THETA_NN
)
<
0.1
;
labPatch
.
shouldBeIntegrated
=
abs
(
srValue
-
tld
::
THETA_NN
)
<
tld
::
CLASSIFIER_MARGIN
;
patches
[
k
].
push_back
(
labPatch
);
//
...
...
modules/tracking/src/tldDetector.cpp
View file @
489f8df9
...
...
@@ -40,6 +40,7 @@
//M*/
#include "tldDetector.hpp"
#include "tracking_utils.hpp"
#include <opencv2/core/utility.hpp>
...
...
@@ -64,27 +65,58 @@ namespace cv
return
p
;
}
double
TLDDetector
::
computeSminus
(
const
Mat_
<
uchar
>&
patch
)
const
{
double
sminus
=
0.0
;
Mat_
<
uchar
>
modelSample
(
STANDARD_PATCH_SIZE
,
STANDARD_PATCH_SIZE
);
for
(
int
i
=
0
;
i
<
*
negNum
;
i
++
)
{
modelSample
.
data
=
&
(
negExp
->
data
[
i
*
225
]);
sminus
=
std
::
max
(
sminus
,
0.5
*
(
tracking_internal
::
computeNCC
(
modelSample
,
patch
)
+
1.0
));
}
return
sminus
;
}
// Calculate Relative similarity of the patch (NN-Model)
double
TLDDetector
::
Sr
(
const
Mat_
<
uchar
>&
patch
)
const
{
double
splus
=
0.0
,
sminus
=
0.0
;
Mat_
<
uchar
>
modelSample
(
STANDARD_PATCH_SIZE
,
STANDARD_PATCH_SIZE
);
Mat_
<
uchar
>
modelSample
(
STANDARD_PATCH_SIZE
,
STANDARD_PATCH_SIZE
);
for
(
int
i
=
0
;
i
<
*
posNum
;
i
++
)
{
modelSample
.
data
=
&
(
posExp
->
data
[
i
*
225
]);
splus
=
std
::
max
(
splus
,
0.5
*
(
NCC
(
modelSample
,
patch
)
+
1.0
));
}
for
(
int
i
=
0
;
i
<
*
negNum
;
i
++
)
{
modelSample
.
data
=
&
(
negExp
->
data
[
i
*
225
]);
sminus
=
std
::
max
(
sminus
,
0.5
*
(
NCC
(
modelSample
,
patch
)
+
1.0
));
splus
=
std
::
max
(
splus
,
0.5
*
(
tracking_internal
::
computeNCC
(
modelSample
,
patch
)
+
1.0
));
}
sminus
=
computeSminus
(
patch
);
if
(
splus
+
sminus
==
0.0
)
return
0.0
;
return
splus
/
(
sminus
+
splus
);
}
std
::
pair
<
double
,
double
>
TLDDetector
::
SrAndSc
(
const
Mat_
<
uchar
>&
patch
)
const
{
double
splusC
=
0.0
,
sminus
=
0.0
,
splus
=
0.0
;
Mat_
<
uchar
>
modelSample
(
STANDARD_PATCH_SIZE
,
STANDARD_PATCH_SIZE
);
int
med
=
tracking_internal
::
getMedian
((
*
timeStampsPositive
));
for
(
int
i
=
0
;
i
<
*
posNum
;
i
++
)
{
modelSample
.
data
=
&
(
posExp
->
data
[
i
*
225
]);
double
s
=
0.5
*
(
tracking_internal
::
computeNCC
(
modelSample
,
patch
)
+
1.0
);
if
((
int
)(
*
timeStampsPositive
)[
i
]
<=
med
)
splusC
=
std
::
max
(
splusC
,
s
);
splus
=
std
::
max
(
splus
,
s
);
}
sminus
=
computeSminus
(
patch
);
double
sr
=
(
splus
+
sminus
==
0.0
)
?
0.
:
splus
/
(
sminus
+
splus
);
double
sc
=
(
splusC
+
sminus
==
0.0
)
?
0.
:
splusC
/
(
sminus
+
splusC
);
return
std
::
pair
<
double
,
double
>
(
sr
,
sc
);
}
#ifdef HAVE_OPENCL
double
TLDDetector
::
ocl_Sr
(
const
Mat_
<
uchar
>&
patch
)
{
...
...
@@ -167,7 +199,7 @@ namespace cv
for
(
int
id
=
0
;
id
<
numOfPatches
;
id
++
)
{
double
spr
=
0.0
,
smr
=
0.0
,
spc
=
0.0
,
smc
=
0
;
int
med
=
getMedian
((
*
timeStampsPositive
));
int
med
=
tracking_internal
::
getMedian
((
*
timeStampsPositive
));
for
(
int
i
=
0
;
i
<
*
posNum
;
i
++
)
{
spr
=
std
::
max
(
spr
,
0.5
*
(
posNCC
.
at
<
float
>
(
id
*
500
+
i
)
+
1.0
));
...
...
@@ -195,20 +227,16 @@ namespace cv
{
double
splus
=
0.0
,
sminus
=
0.0
;
Mat_
<
uchar
>
modelSample
(
STANDARD_PATCH_SIZE
,
STANDARD_PATCH_SIZE
);
int
med
=
getMedian
((
*
timeStampsPositive
));
int
med
=
tracking_internal
::
getMedian
((
*
timeStampsPositive
));
for
(
int
i
=
0
;
i
<
*
posNum
;
i
++
)
{
if
((
int
)(
*
timeStampsPositive
)[
i
]
<=
med
)
{
modelSample
.
data
=
&
(
posExp
->
data
[
i
*
225
]);
splus
=
std
::
max
(
splus
,
0.5
*
(
NCC
(
modelSample
,
patch
)
+
1.0
));
splus
=
std
::
max
(
splus
,
0.5
*
(
tracking_internal
::
compute
NCC
(
modelSample
,
patch
)
+
1.0
));
}
}
for
(
int
i
=
0
;
i
<
*
negNum
;
i
++
)
{
modelSample
.
data
=
&
(
negExp
->
data
[
i
*
225
]);
sminus
=
std
::
max
(
sminus
,
0.5
*
(
NCC
(
modelSample
,
patch
)
+
1.0
));
}
sminus
=
computeSminus
(
patch
);
if
(
splus
+
sminus
==
0.0
)
return
0.0
;
...
...
@@ -249,7 +277,7 @@ namespace cv
Mat
resNCC
=
devNCC
.
getMat
(
ACCESS_READ
);
int
med
=
getMedian
((
*
timeStampsPositive
));
int
med
=
tracking_internal
::
getMedian
((
*
timeStampsPositive
));
for
(
int
i
=
0
;
i
<
*
posNum
;
i
++
)
if
((
int
)(
*
timeStampsPositive
)[
i
]
<=
med
)
splus
=
std
::
max
(
splus
,
0.5
*
(
resNCC
.
at
<
float
>
(
i
)
+
1.0
));
...
...
@@ -316,9 +344,9 @@ namespace cv
resample
(
detectorF
->
resized_imgs
[
detectorF
->
ensScaleIDs
[
ind
]],
Rect2d
(
detectorF
->
ensBuffer
[
ind
],
initSizeF
),
detectorF
->
standardPatches
[
ind
]);
detectorF
->
scValues
[
ind
]
=
detectorF
->
Sc
(
detectorF
->
standardPatches
[
ind
])
;
detectorF
->
srValues
[
ind
]
=
detectorF
->
Sr
(
detectorF
->
standardPatches
[
ind
])
;
std
::
pair
<
double
,
double
>
values
=
detectorF
->
SrAndSc
(
detectorF
->
standardPatches
[
ind
]);
detectorF
->
scValues
[
ind
]
=
values
.
second
;
detectorF
->
srValues
[
ind
]
=
values
.
first
;
}
}
...
...
@@ -412,15 +440,17 @@ namespace cv
LabeledPatch
labPatch
;
double
curScale
=
pow
(
SCALE_STEP
,
ensScaleIDs
[
i
]);
labPatch
.
rect
=
Rect2d
(
ensBuffer
[
i
].
x
*
curScale
,
ensBuffer
[
i
].
y
*
curScale
,
initSize
.
width
*
curScale
,
initSize
.
height
*
curScale
);
labPatch
.
Sc
=
scValues
[
i
];
//printf("max sc %f\n", labPatch.Sc);
const
double
srValue
=
srValues
[
i
];
const
double
scValue
=
scValues
[
i
];
////To fix: Check the paper, probably this cause wrong learning
//
labPatch
.
isObject
=
srValue
>
THETA_NN
;
labPatch
.
shouldBeIntegrated
=
abs
(
srValue
-
THETA_NN
)
<
0.1
;
patches
.
push_back
(
labPatch
);
labPatch
.
isObject
=
srValue
>
THETA_NN
;
labPatch
.
shouldBeIntegrated
=
abs
(
srValue
-
THETA_NN
)
<
CLASSIFIER_MARGIN
;
patches
.
push_back
(
labPatch
);
//
if
(
!
labPatch
.
isObject
)
...
...
@@ -440,7 +470,7 @@ namespace cv
}
}
if
(
maxSc
<
0
)
if
(
maxSc
<
0
)
return
false
;
else
{
...
...
@@ -538,7 +568,7 @@ namespace cv
////To fix: Check the paper, probably this cause wrong learning
//
labPatch
.
isObject
=
srValue
>
THETA_NN
;
labPatch
.
shouldBeIntegrated
=
abs
(
srValue
-
THETA_NN
)
<
0.1
;
labPatch
.
shouldBeIntegrated
=
abs
(
srValue
-
THETA_NN
)
<
CLASSIFIER_MARGIN
;
patches
.
push_back
(
labPatch
);
//
...
...
modules/tracking/src/tldDetector.hpp
View file @
489f8df9
...
...
@@ -57,8 +57,9 @@ namespace cv
const
int
MEASURES_PER_CLASSIFIER
=
13
;
const
int
GRIDSIZE
=
15
;
const
int
DOWNSCALE_MODE
=
cv
::
INTER_LINEAR
;
const
double
THETA_NN
=
0.50
;
const
double
THETA_NN
=
0.5
;
const
double
CORE_THRESHOLD
=
0.5
;
const
double
CLASSIFIER_MARGIN
=
0.1
;
const
double
SCALE_STEP
=
1.2
;
const
double
ENSEMBLE_THRESHOLD
=
0.5
;
const
double
VARIANCE_THRESHOLD
=
0.5
;
...
...
@@ -77,6 +78,7 @@ namespace cv
void
prepareClassifiers
(
int
rowstep
);
double
Sr
(
const
Mat_
<
uchar
>&
patch
)
const
;
double
Sc
(
const
Mat_
<
uchar
>&
patch
)
const
;
std
::
pair
<
double
,
double
>
SrAndSc
(
const
Mat_
<
uchar
>&
patch
)
const
;
#ifdef HAVE_OPENCL
double
ocl_Sr
(
const
Mat_
<
uchar
>&
patch
);
double
ocl_Sc
(
const
Mat_
<
uchar
>&
patch
);
...
...
@@ -101,6 +103,7 @@ namespace cv
{
Rect2d
rect
;
bool
isObject
,
shouldBeIntegrated
;
double
Sc
;
};
bool
detect
(
const
Mat
&
img
,
const
Mat
&
imgBlurred
,
Rect2d
&
res
,
std
::
vector
<
LabeledPatch
>&
patches
,
Size
initSize
);
bool
ocl_detect
(
const
Mat
&
img
,
const
Mat
&
imgBlurred
,
Rect2d
&
res
,
std
::
vector
<
LabeledPatch
>&
patches
,
Size
initSize
);
...
...
@@ -108,6 +111,9 @@ namespace cv
friend
class
MyMouseCallbackDEBUG
;
static
void
computeIntegralImages
(
const
Mat
&
img
,
Mat_
<
double
>&
intImgP
,
Mat_
<
double
>&
intImgP2
){
integral
(
img
,
intImgP
,
intImgP2
,
CV_64F
);
}
static
inline
bool
patchVariance
(
Mat_
<
double
>&
intImgP
,
Mat_
<
double
>&
intImgP2
,
double
*
originalVariance
,
Point
pt
,
Size
size
);
protected
:
double
computeSminus
(
const
Mat_
<
uchar
>&
patch
)
const
;
};
...
...
modules/tracking/src/tldModel.cpp
View file @
489f8df9
...
...
@@ -87,9 +87,9 @@ namespace cv
//Generate initial positive samples and put them to the model
positiveExamples
.
reserve
(
200
);
for
(
int
i
=
0
;
i
<
(
int
)
closest
.
size
();
i
++
)
for
(
size_t
i
=
0
;
i
<
closest
.
size
();
i
++
)
{
for
(
in
t
j
=
0
;
j
<
20
;
j
++
)
for
(
size_
t
j
=
0
;
j
<
20
;
j
++
)
{
Point2f
center
;
Size2f
size
;
...
...
@@ -102,13 +102,15 @@ namespace cv
resample
(
scaledImg
,
RotatedRect
(
center
,
size
,
angle
),
standardPatch
);
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
y
=
0
;
y
<
standardPatch
.
rows
;
y
++
)
{
uchar
*
patchRow
=
standardPatch
.
ptr
(
y
);
for
(
int
x
=
0
;
x
<
standardPatch
.
cols
;
x
++
)
{
int
newValue
=
patchRow
[
x
]
+
cvRound
(
rng
.
gaussian
(
5.0
));
patchRow
[
x
]
=
saturate_cast
<
uchar
>
(
newValue
);
}
}
#ifdef BLUR_AS_VADIM
GaussianBlur
(
standardPatch
,
blurredPatch
,
GaussBlurKernelSize
,
0.0
);
...
...
modules/tracking/src/tldTracker.cpp
View file @
489f8df9
...
...
@@ -41,7 +41,6 @@
#include "tldTracker.hpp"
namespace
cv
{
...
...
@@ -141,38 +140,38 @@ bool TrackerTLDImpl::updateImpl(const Mat& image, Rect2d& boundingBox)
std
::
vector
<
Rect2d
>
candidates
;
std
::
vector
<
double
>
candidatesRes
;
bool
trackerNeedsReInit
=
false
;
bool
DETECT_FLG
=
false
;
for
(
int
i
=
0
;
i
<
2
;
i
++
)
bool
DETECT_FLG
=
false
;
//run tracker
Rect2d
tmpCandid
=
boundingBox
;
if
(
!
data
->
failedLastTime
&&
trackerProxy
->
update
(
image
,
tmpCandid
))
{
Rect2d
tmpCandid
=
boundingBox
;
candidates
.
push_back
(
tmpCandid
);
resample
(
image_gray
,
tmpCandid
,
standardPatch
);
candidatesRes
.
push_back
(
tldModel
->
detector
->
Sc
(
standardPatch
));
}
else
trackerNeedsReInit
=
true
;
if
(
i
==
1
)
{
//run detector
tmpCandid
=
boundingBox
;
#ifdef HAVE_OPENCL
if
(
ocl
::
hav
eOpenCL
())
DETECT_FLG
=
tldModel
->
detector
->
ocl_detect
(
imageForDetector
,
image_blurred
,
tmpCandid
,
detectorResults
,
tldModel
->
getMinSize
());
else
if
(
false
)
//ocl::us
eOpenCL())
DETECT_FLG
=
tldModel
->
detector
->
ocl_detect
(
imageForDetector
,
image_blurred
,
tmpCandid
,
detectorResults
,
tldModel
->
getMinSize
());
else
#endif
DETECT_FLG
=
tldModel
->
detector
->
detect
(
imageForDetector
,
image_blurred
,
tmpCandid
,
detectorResults
,
tldModel
->
getMinSize
());
}
if
(
(
(
i
==
0
)
&&
!
data
->
failedLastTime
&&
trackerProxy
->
update
(
image
,
tmpCandid
)
)
||
(
DETECT_FLG
))
{
candidates
.
push_back
(
tmpCandid
);
if
(
i
==
0
)
resample
(
image_gray
,
tmpCandid
,
standardPatch
);
else
resample
(
imageForDetector
,
tmpCandid
,
standardPatch
);
candidatesRes
.
push_back
(
tldModel
->
detector
->
Sc
(
standardPatch
));
}
else
{
if
(
i
==
0
)
trackerNeedsReInit
=
true
;
}
DETECT_FLG
=
tldModel
->
detector
->
detect
(
imageForDetector
,
image_blurred
,
tmpCandid
,
detectorResults
,
tldModel
->
getMinSize
());
if
(
DETECT_FLG
)
{
candidates
.
push_back
(
tmpCandid
);
resample
(
imageForDetector
,
tmpCandid
,
standardPatch
);
candidatesRes
.
push_back
(
tldModel
->
detector
->
Sc
(
standardPatch
));
}
std
::
vector
<
double
>::
iterator
it
=
std
::
max_element
(
candidatesRes
.
begin
(),
candidatesRes
.
end
());
if
(
it
==
candidatesRes
.
end
()
)
if
(
it
==
candidatesRes
.
end
()
)
//candidates are empty
{
data
->
confident
=
false
;
data
->
failedLastTime
=
true
;
...
...
@@ -221,7 +220,7 @@ bool TrackerTLDImpl::updateImpl(const Mat& image, Rect2d& boundingBox)
tldModel
->
integrateRelabeled
(
imageForDetector
,
image_blurred
,
detectorResults
);
pExpert
.
additionalExamples
(
examplesForModel
,
examplesForEnsemble
);
#ifdef HAVE_OPENCL
if
(
ocl
::
hav
eOpenCL
())
if
(
false
)
//ocl::us
eOpenCL())
tldModel
->
ocl_integrateAdditional
(
examplesForModel
,
examplesForEnsemble
,
true
);
else
#endif
...
...
@@ -230,7 +229,7 @@ bool TrackerTLDImpl::updateImpl(const Mat& image, Rect2d& boundingBox)
nExpert
.
additionalExamples
(
examplesForModel
,
examplesForEnsemble
);
#ifdef HAVE_OPENCL
if
(
ocl
::
hav
eOpenCL
())
if
(
false
)
//ocl::us
eOpenCL())
tldModel
->
ocl_integrateAdditional
(
examplesForModel
,
examplesForEnsemble
,
false
);
else
#endif
...
...
@@ -257,12 +256,13 @@ int TrackerTLDImpl::Pexpert::additionalExamples(std::vector<Mat_<uchar> >& examp
double
scale
=
scaleAndBlur
(
img_
,
cvRound
(
log
(
1.0
*
resultBox_
.
width
/
(
initSize_
.
width
))
/
log
(
SCALE_STEP
)),
scaledImg
,
blurredImg
,
GaussBlurKernelSize
,
SCALE_STEP
);
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
);
for
(
int
i
=
0
;
i
<
(
int
)
closest
.
size
();
i
++
)
for
(
size_t
i
=
0
;
i
<
closest
.
size
();
i
++
)
{
for
(
in
t
j
=
0
;
j
<
10
;
j
++
)
for
(
size_
t
j
=
0
;
j
<
10
;
j
++
)
{
Point2f
center
;
Size2f
size
;
...
...
@@ -273,21 +273,24 @@ int TrackerTLDImpl::Pexpert::additionalExamples(std::vector<Mat_<uchar> >& examp
size
.
height
=
(
float
)(
closest
[
i
].
height
*
rng
.
uniform
((
double
)
0.99
,
(
double
)
1.01
));
float
angle
=
(
float
)
rng
.
uniform
(
-
5.0
,
5.0
);
resample
(
scaledImg
,
RotatedRect
(
center
,
size
,
angle
),
standardPatch
);
for
(
int
y
=
0
;
y
<
standardPatch
.
rows
;
y
++
)
{
uchar
*
patchRow
=
standardPatch
.
ptr
(
y
);
for
(
int
x
=
0
;
x
<
standardPatch
.
cols
;
x
++
)
{
standardPatch
(
x
,
y
)
+=
(
uchar
)
rng
.
gaussian
(
5.0
);
int
newValue
=
patchRow
[
x
]
+
cvRound
(
rng
.
gaussian
(
5.0
));
patchRow
[
x
]
=
saturate_cast
<
uchar
>
(
newValue
);
}
}
#ifdef BLUR_AS_VADIM
examplesForModel
.
push_back
(
standardPatch
);
#if defined BLUR_AS_VADIM
GaussianBlur
(
standardPatch
,
blurredPatch
,
GaussBlurKernelSize
,
0.0
);
resize
(
blurredPatch
,
blurredPatch
,
initSize_
);
#else
resample
(
blurredImg
,
RotatedRect
(
center
,
size
,
angle
),
blurredPatch
);
#endif
resample
(
scaledImg
,
RotatedRect
(
center
,
size
,
angle
),
standardPatch
);
examplesForModel
.
push_back
(
standardPatch
);
examplesForEnsemble
.
push_back
(
blurredPatch
);
}
}
...
...
modules/tracking/src/tldTracker.hpp
View file @
489f8df9
...
...
@@ -112,7 +112,7 @@ private:
};
#
define
BLUR_AS_VADIM
#
undef
BLUR_AS_VADIM
#undef CLOSED_LOOP
class
TrackerTLDImpl
:
public
TrackerTLD
...
...
modules/tracking/src/tldUtils.cpp
View file @
489f8df9
...
...
@@ -151,52 +151,12 @@ void getClosestN(std::vector<Rect2d>& scanGrid, Rect2d bBox, int n, std::vector<
double
variance
(
const
Mat
&
img
)
{
double
p
=
0
,
p2
=
0
;
for
(
int
i
=
0
;
i
<
img
.
rows
;
i
++
)
{
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
=
sum
(
img
)(
0
);
p2
=
norm
(
img
,
NORM_L2SQR
);
p
/=
(
img
.
cols
*
img
.
rows
);
p2
/=
(
img
.
cols
*
img
.
rows
);
return
p2
-
p
*
p
;
}
//Normalized Correlation Coefficient
double
NCC
(
const
Mat_
<
uchar
>&
patch1
,
const
Mat_
<
uchar
>&
patch2
)
{
CV_Assert
(
patch1
.
rows
==
patch2
.
rows
);
CV_Assert
(
patch1
.
cols
==
patch2
.
cols
);
int
N
=
patch1
.
rows
*
patch1
.
cols
;
int
s1
=
0
,
s2
=
0
,
n1
=
0
,
n2
=
0
,
prod
=
0
;
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
);
s1
+=
p1
;
s2
+=
p2
;
n1
+=
(
p1
*
p1
);
n2
+=
(
p2
*
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
ares
=
(
sq2
==
0
)
?
sq1
/
abs
(
sq1
)
:
(
prod
-
s1
*
s2
/
N
)
/
sq1
/
sq2
;
return
ares
;
}
int
getMedian
(
const
std
::
vector
<
int
>&
values
,
int
size
)
{
if
(
size
==
-
1
)
size
=
(
int
)
values
.
size
();
std
::
vector
<
int
>
copy
(
values
.
begin
(),
values
.
begin
()
+
size
);
std
::
sort
(
copy
.
begin
(),
copy
.
end
());
if
(
size
%
2
==
0
)
return
(
copy
[
size
/
2
-
1
]
+
copy
[
size
/
2
])
/
2
;
else
return
copy
[(
size
-
1
)
/
2
];
return
p2
-
p
*
p
;
}
//Overlap between two BB
...
...
modules/tracking/src/tldUtils.hpp
View file @
489f8df9
...
...
@@ -46,13 +46,8 @@ namespace cv
void
resample
(
const
Mat
&
img
,
const
Rect2d
&
r2
,
Mat_
<
uchar
>&
samples
);
/** Computes the variance of single given image.*/
double
variance
(
const
Mat
&
img
);
/** Computes normalized corellation coefficient between the two patches (they should be
* of the same size).*/
double
NCC
(
const
Mat_
<
uchar
>&
patch1
,
const
Mat_
<
uchar
>&
patch2
);
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
);
int
getMedian
(
const
std
::
vector
<
int
>&
values
,
int
size
=
-
1
);
}
}
...
...
modules/tracking/src/trackerMedianFlow.cpp
View file @
489f8df9
...
...
@@ -42,6 +42,7 @@
#include "precomp.hpp"
#include "opencv2/video/tracking.hpp"
#include "opencv2/imgproc.hpp"
#include "tracking_utils.hpp"
#include <algorithm>
#include <limits.h>
...
...
@@ -94,12 +95,6 @@ private:
TrackerMedianFlow
::
Params
params
;
};
template
<
typename
T
>
T
getMedian
(
const
std
::
vector
<
T
>&
values
);
template
<
typename
T
>
T
getMedianAndDoPartition
(
std
::
vector
<
T
>&
values
);
Mat
getPatch
(
Mat
image
,
Size
patch_size
,
Point2f
patch_center
)
{
Mat
patch
;
...
...
@@ -282,7 +277,7 @@ bool TrackerMedianFlowImpl::medianFlowImpl(Mat oldImage,Mat newImage,Rect2d& old
di
[
i
]
-=
mDisplacement
;
displacements
.
push_back
((
float
)
sqrt
(
di
[
i
].
ddot
(
di
[
i
])));
}
float
median_displacements
=
getMedianAndDoPartition
(
displacements
);
float
median_displacements
=
tracking_internal
::
getMedianAndDoPartition
(
displacements
);
dprintf
((
"
\t
median of length of difference of displacements = %f
\n
"
,
median_displacements
));
if
(
median_displacements
>
params
.
maxMedianLengthOfDisplacementDifference
){
dprintf
((
"
\t
median flow tracker returns false due to big median length of difference between displacements
\n
"
));
...
...
@@ -310,10 +305,10 @@ Rect2d TrackerMedianFlowImpl::vote(const std::vector<Point2f>& oldPoints,const s
float
xshift
=
0
,
yshift
=
0
;
std
::
vector
<
float
>
buf_for_location
(
n
,
0.
);
for
(
size_t
i
=
0
;
i
<
n
;
i
++
){
buf_for_location
[
i
]
=
newPoints
[
i
].
x
-
oldPoints
[
i
].
x
;
}
xshift
=
getMedianAndDoPartition
(
buf_for_location
);
xshift
=
tracking_internal
::
getMedianAndDoPartition
(
buf_for_location
);
newCenter
.
x
+=
xshift
;
for
(
size_t
i
=
0
;
i
<
n
;
i
++
){
buf_for_location
[
i
]
=
newPoints
[
i
].
y
-
oldPoints
[
i
].
y
;
}
yshift
=
getMedianAndDoPartition
(
buf_for_location
);
yshift
=
tracking_internal
::
getMedianAndDoPartition
(
buf_for_location
);
newCenter
.
y
+=
yshift
;
mD
=
Point2f
((
float
)
xshift
,(
float
)
yshift
);
...
...
@@ -327,7 +322,7 @@ Rect2d TrackerMedianFlowImpl::vote(const std::vector<Point2f>& oldPoints,const s
}
}
double
scale
=
getMedianAndDoPartition
(
buf_for_scale
);
double
scale
=
tracking_internal
::
getMedianAndDoPartition
(
buf_for_scale
);
dprintf
((
"xshift, yshift, scale = %f %f %f
\n
"
,
xshift
,
yshift
,
scale
));
newRect
.
x
=
newCenter
.
x
-
scale
*
oldRect
.
width
/
2.0
;
newRect
.
y
=
newCenter
.
y
-
scale
*
oldRect
.
height
/
2.0
;
...
...
@@ -338,7 +333,6 @@ Rect2d TrackerMedianFlowImpl::vote(const std::vector<Point2f>& oldPoints,const s
return
newRect
;
}
#if 0
void TrackerMedianFlowImpl::computeStatistics(std::vector<float>& data,int size){
int binnum=10;
...
...
@@ -355,7 +349,6 @@ void TrackerMedianFlowImpl::computeStatistics(std::vector<float>& data,int size)
}
}
#endif
void
TrackerMedianFlowImpl
::
check_FB
(
const
std
::
vector
<
Mat
>&
oldImagePyr
,
const
std
::
vector
<
Mat
>&
newImagePyr
,
const
std
::
vector
<
Point2f
>&
oldPoints
,
const
std
::
vector
<
Point2f
>&
newPoints
,
std
::
vector
<
bool
>&
status
){
...
...
@@ -373,7 +366,7 @@ void TrackerMedianFlowImpl::check_FB(const std::vector<Mat>& oldImagePyr, const
for
(
size_t
i
=
0
;
i
<
oldPoints
.
size
();
i
++
){
FBerror
[
i
]
=
(
float
)
norm
(
oldPoints
[
i
]
-
pointsToTrackReprojection
[
i
]);
}
float
FBerrorMedian
=
getMedian
(
FBerror
);
float
FBerrorMedian
=
tracking_internal
::
getMedian
(
FBerror
);
dprintf
((
"point median=%f
\n
"
,
FBerrorMedian
));
dprintf
((
"FBerrorMedian=%f
\n
"
,
FBerrorMedian
));
for
(
size_t
i
=
0
;
i
<
oldPoints
.
size
();
i
++
){
...
...
@@ -390,51 +383,14 @@ void TrackerMedianFlowImpl::check_NCC(const Mat& oldImage,const Mat& newImage,
p1
=
getPatch
(
oldImage
,
params
.
winSizeNCC
,
oldPoints
[
i
]);
p2
=
getPatch
(
newImage
,
params
.
winSizeNCC
,
newPoints
[
i
]);
const
int
patch_area
=
params
.
winSizeNCC
.
area
();
double
s1
=
sum
(
p1
)(
0
),
s2
=
sum
(
p2
)(
0
);
double
n1
=
norm
(
p1
),
n2
=
norm
(
p2
);
double
prod
=
p1
.
dot
(
p2
);
double
sq1
=
sqrt
(
n1
*
n1
-
s1
*
s1
/
patch_area
),
sq2
=
sqrt
(
n2
*
n2
-
s2
*
s2
/
patch_area
);
double
ares
=
(
sq2
==
0
)
?
sq1
/
abs
(
sq1
)
:
(
prod
-
s1
*
s2
/
patch_area
)
/
sq1
/
sq2
;
NCC
[
i
]
=
(
float
)
ares
;
NCC
[
i
]
=
(
float
)
tracking_internal
::
computeNCC
(
p1
,
p2
);
}
float
median
=
getMedian
(
NCC
);
float
median
=
tracking_internal
::
getMedian
(
NCC
);
for
(
size_t
i
=
0
;
i
<
oldPoints
.
size
();
i
++
)
{
status
[
i
]
=
status
[
i
]
&&
(
NCC
[
i
]
>=
median
);
}
}
template
<
typename
T
>
T
getMedian
(
const
std
::
vector
<
T
>&
values
)
{
std
::
vector
<
T
>
copy
(
values
);
return
getMedianAndDoPartition
(
copy
);
}
template
<
typename
T
>
T
getMedianAndDoPartition
(
std
::
vector
<
T
>&
values
)
{
size_t
size
=
values
.
size
();
if
(
size
%
2
==
0
)
{
std
::
nth_element
(
values
.
begin
(),
values
.
begin
()
+
size
/
2
-
1
,
values
.
end
());
T
firstMedian
=
values
[
size
/
2
-
1
];
std
::
nth_element
(
values
.
begin
(),
values
.
begin
()
+
size
/
2
,
values
.
end
());
T
secondMedian
=
values
[
size
/
2
];
return
(
firstMedian
+
secondMedian
)
/
(
T
)
2
;
}
else
{
size_t
medianIndex
=
(
size
-
1
)
/
2
;
std
::
nth_element
(
values
.
begin
(),
values
.
begin
()
+
medianIndex
,
values
.
end
());
return
values
[
medianIndex
];
}
}
}
/* anonymous namespace */
namespace
cv
...
...
modules/tracking/src/tracking_utils.cpp
0 → 100644
View file @
489f8df9
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "tracking_utils.hpp"
using
namespace
cv
;
double
tracking_internal
::
computeNCC
(
const
Mat
&
patch1
,
const
Mat
&
patch2
)
{
CV_Assert
(
patch1
.
rows
==
patch2
.
rows
,
patch1
.
cols
==
patch2
.
cols
);
int
N
=
patch1
.
rows
*
patch1
.
cols
;
if
(
N
<=
1000
&&
patch1
.
type
()
==
CV_8U
&&
patch2
.
type
()
==
CV_8U
)
{
unsigned
s1
=
0
,
s2
=
0
;
unsigned
n1
=
0
,
n2
=
0
;
unsigned
prod
=
0
;
if
(
patch1
.
isContinuous
()
&&
patch2
.
isContinuous
())
{
const
uchar
*
p1Ptr
=
patch1
.
ptr
<
uchar
>
(
0
);
const
uchar
*
p2Ptr
=
patch2
.
ptr
<
uchar
>
(
0
);
for
(
int
j
=
0
;
j
<
N
;
j
++
)
{
s1
+=
p1Ptr
[
j
];
s2
+=
p2Ptr
[
j
];
n1
+=
p1Ptr
[
j
]
*
p1Ptr
[
j
];
n2
+=
p2Ptr
[
j
]
*
p2Ptr
[
j
];
prod
+=
p1Ptr
[
j
]
*
p2Ptr
[
j
];
}
}
else
{
for
(
int
i
=
0
;
i
<
patch1
.
rows
;
i
++
)
{
const
uchar
*
p1Ptr
=
patch1
.
ptr
<
uchar
>
(
i
);
const
uchar
*
p2Ptr
=
patch2
.
ptr
<
uchar
>
(
i
);
for
(
int
j
=
0
;
j
<
patch1
.
cols
;
j
++
)
{
s1
+=
p1Ptr
[
j
];
s2
+=
p2Ptr
[
j
];
n1
+=
p1Ptr
[
j
]
*
p1Ptr
[
j
];
n2
+=
p2Ptr
[
j
]
*
p2Ptr
[
j
];
prod
+=
p1Ptr
[
j
]
*
p2Ptr
[
j
];
}
}
}
double
sq1
=
sqrt
(
std
::
max
(
0.0
,
n1
-
1.0
*
s1
*
s1
/
N
));
double
sq2
=
sqrt
(
std
::
max
(
0.0
,
n2
-
1.0
*
s2
*
s2
/
N
));
return
(
sq2
==
0
)
?
sq1
/
abs
(
sq1
)
:
(
prod
-
1.0
*
s1
*
s2
/
N
)
/
sq1
/
sq2
;
}
else
{
double
s1
=
sum
(
patch1
)(
0
);
double
s2
=
sum
(
patch2
)(
0
);
double
n1
=
norm
(
patch1
,
NORM_L2SQR
);
double
n2
=
norm
(
patch2
,
NORM_L2SQR
);
double
prod
=
patch1
.
dot
(
patch2
);
double
sq1
=
sqrt
(
std
::
max
(
0.0
,
n1
-
1.0
*
s1
*
s1
/
N
));
double
sq2
=
sqrt
(
std
::
max
(
0.0
,
n2
-
1.0
*
s2
*
s2
/
N
));
return
(
sq2
==
0
)
?
sq1
/
abs
(
sq1
)
:
(
prod
-
s1
*
s2
/
N
)
/
sq1
/
sq2
;
}
}
modules/tracking/src/tracking_utils.hpp
0 → 100644
View file @
489f8df9
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef __OPENCV_TRACKING_UTILS_HPP__
#include "precomp.hpp"
#include <algorithm>
namespace
cv
{
namespace
tracking_internal
{
/** Computes normalized corellation coefficient between the two patches (they should be
* of the same size).*/
double
computeNCC
(
const
Mat
&
patch1
,
const
Mat
&
patch2
);
template
<
typename
T
>
T
getMedianAndDoPartition
(
std
::
vector
<
T
>&
values
)
{
size_t
size
=
values
.
size
();
if
(
size
%
2
==
0
)
{
std
::
nth_element
(
values
.
begin
(),
values
.
begin
()
+
size
/
2
-
1
,
values
.
end
());
T
firstMedian
=
values
[
size
/
2
-
1
];
std
::
nth_element
(
values
.
begin
(),
values
.
begin
()
+
size
/
2
,
values
.
end
());
T
secondMedian
=
values
[
size
/
2
];
return
(
firstMedian
+
secondMedian
)
/
(
T
)
2
;
}
else
{
size_t
medianIndex
=
(
size
-
1
)
/
2
;
std
::
nth_element
(
values
.
begin
(),
values
.
begin
()
+
medianIndex
,
values
.
end
());
return
values
[
medianIndex
];
}
}
template
<
typename
T
>
T
getMedian
(
const
std
::
vector
<
T
>&
values
)
{
std
::
vector
<
T
>
copy
(
values
);
return
getMedianAndDoPartition
(
copy
);
}
}
}
#endif
modules/tracking/test/test_trackers.cpp
View file @
489f8df9
...
...
@@ -459,9 +459,9 @@ TEST_P(DistanceAndOverlap, KCF)
test
.
run
();
}
TEST_P
(
DistanceAndOverlap
,
DISABLED_
TLD
)
TEST_P
(
DistanceAndOverlap
,
TLD
)
{
TrackerTest
test
(
TrackerTLD
::
create
(),
dataset
,
60
,
.4
f
,
NoTransform
);
TrackerTest
test
(
TrackerTLD
::
create
(),
dataset
,
40
,
.45
f
,
NoTransform
);
test
.
run
();
}
...
...
@@ -497,9 +497,9 @@ TEST_P(DistanceAndOverlap, Shifted_Data_KCF)
test
.
run
();
}
TEST_P
(
DistanceAndOverlap
,
DISABLED_
Shifted_Data_TLD
)
TEST_P
(
DistanceAndOverlap
,
Shifted_Data_TLD
)
{
TrackerTest
test
(
TrackerTLD
::
create
(),
dataset
,
120
,
.2
f
,
CenterShiftLeft
);
TrackerTest
test
(
TrackerTLD
::
create
(),
dataset
,
30
,
.35
f
,
CenterShiftLeft
);
test
.
run
();
}
...
...
@@ -534,9 +534,9 @@ TEST_P(DistanceAndOverlap, Scaled_Data_KCF)
test
.
run
();
}
TEST_P
(
DistanceAndOverlap
,
DISABLED_
Scaled_Data_TLD
)
TEST_P
(
DistanceAndOverlap
,
Scaled_Data_TLD
)
{
TrackerTest
test
(
TrackerTLD
::
create
(),
dataset
,
12
0
,
.45
f
,
Scale_1_1
);
TrackerTest
test
(
TrackerTLD
::
create
(),
dataset
,
3
0
,
.45
f
,
Scale_1_1
);
test
.
run
();
}
...
...
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