Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
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
Commits
2556bb04
Commit
2556bb04
authored
Jul 16, 2012
by
Maria Dimashova
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
changed tests for rotation/scale invariance of descriptors
parent
ad7a6ec4
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
457 additions
and
530 deletions
+457
-530
test_rotation_and_scale_invariance.cpp
...es/features2d/test/test_rotation_and_scale_invariance.cpp
+236
-274
test_rotation_and_scale_invariance.cpp
modules/nonfree/test/test_rotation_and_scale_invariance.cpp
+221
-256
No files found.
modules/features2d/test/test_rotation_and_scale_invariance.cpp
View file @
2556bb04
...
...
@@ -53,7 +53,7 @@ const string IMAGE_BIKES = "/detectors_descriptors_evaluation/images_datasets/bi
static
Mat
generateHomography
(
float
angle
)
{
// angle - rotation around Oz in degrees
// angle - rotation around Oz in degrees
float
angleRadian
=
angle
*
CV_PI
/
180.
;
Mat
H
=
Mat
::
eye
(
3
,
3
,
CV_32FC1
);
H
.
at
<
float
>
(
0
,
0
)
=
H
.
at
<
float
>
(
1
,
1
)
=
std
::
cos
(
angleRadian
);
...
...
@@ -66,7 +66,7 @@ Mat generateHomography(float angle)
static
Mat
rotateImage
(
const
Mat
&
srcImage
,
float
angle
,
Mat
&
dstImage
,
Mat
&
dstMask
)
{
// angle - rotation around Oz in degrees
// angle - rotation around Oz in degrees
float
diag
=
std
::
sqrt
(
static_cast
<
float
>
(
srcImage
.
cols
*
srcImage
.
cols
+
srcImage
.
rows
*
srcImage
.
rows
));
Mat
LUShift
=
Mat
::
eye
(
3
,
3
,
CV_32FC1
);
// left up
LUShift
.
at
<
float
>
(
0
,
2
)
=
-
srcImage
.
cols
/
2
;
...
...
@@ -85,6 +85,32 @@ Mat rotateImage(const Mat& srcImage, float angle, Mat& dstImage, Mat& dstMask)
return
H
;
}
void
rotateKeyPoints
(
const
vector
<
KeyPoint
>&
src
,
const
Mat
&
H
,
float
angle
,
vector
<
KeyPoint
>&
dst
)
{
// suppose that H is rotation given from rotateImage() and angle has value passed to rotateImage()
vector
<
Point2f
>
srcCenters
,
dstCenters
;
KeyPoint
::
convert
(
src
,
srcCenters
);
perspectiveTransform
(
srcCenters
,
dstCenters
,
H
);
dst
=
src
;
for
(
size_t
i
=
0
;
i
<
dst
.
size
();
i
++
)
{
dst
[
i
].
pt
=
dstCenters
[
i
];
float
dstAngle
=
src
[
i
].
angle
+
angle
;
if
(
dstAngle
>=
360.
f
)
dstAngle
-=
360.
f
;
dst
[
i
].
angle
=
dstAngle
;
}
}
void
scaleKeyPoints
(
const
vector
<
KeyPoint
>&
src
,
vector
<
KeyPoint
>&
dst
,
float
scale
)
{
dst
.
resize
(
src
.
size
());
for
(
size_t
i
=
0
;
i
<
src
.
size
();
i
++
)
dst
[
i
]
=
KeyPoint
(
src
[
i
].
pt
.
x
*
scale
,
src
[
i
].
pt
.
y
*
scale
,
src
[
i
].
size
*
scale
);
}
static
float
calcCirclesIntersectArea
(
const
Point2f
&
p0
,
float
r0
,
const
Point2f
&
p1
,
float
r1
)
{
...
...
@@ -119,45 +145,45 @@ float calcIntersectRatio(const Point2f& p0, float r0, const Point2f& p1, float r
return
intersectArea
/
unionArea
;
}
static
static
void
matchKeyPoints
(
const
vector
<
KeyPoint
>&
keypoints0
,
const
Mat
&
H
,
const
vector
<
KeyPoint
>&
keypoints1
,
vector
<
DMatch
>&
matches
)
const
vector
<
KeyPoint
>&
keypoints1
,
vector
<
DMatch
>&
matches
)
{
vector
<
Point2f
>
points0
;
vector
<
Point2f
>
points0
;
KeyPoint
::
convert
(
keypoints0
,
points0
);
Mat
points0t
;
if
(
H
.
empty
())
points0t
=
Mat
(
points0
);
else
perspectiveTransform
(
Mat
(
points0
),
points0t
,
H
);
matches
.
clear
();
vector
<
uchar
>
usedMask
(
keypoints1
.
size
(),
0
);
for
(
size_t
i0
=
0
;
i0
<
keypoints0
.
size
();
i0
++
)
{
int
nearestPointIndex
=
-
1
;
if
(
H
.
empty
())
points0t
=
Mat
(
points0
);
else
perspectiveTransform
(
Mat
(
points0
),
points0t
,
H
);
matches
.
clear
();
vector
<
uchar
>
usedMask
(
keypoints1
.
size
(),
0
);
for
(
size_t
i0
=
0
;
i0
<
keypoints0
.
size
();
i0
++
)
{
int
nearestPointIndex
=
-
1
;
float
maxIntersectRatio
=
0.
f
;
const
float
r0
=
0.5
f
*
keypoints0
[
i0
].
size
;
for
(
size_t
i1
=
0
;
i1
<
keypoints1
.
size
();
i1
++
)
{
if
(
nearestPointIndex
>=
0
&&
usedMask
[
i1
])
continue
;
if
(
nearestPointIndex
>=
0
&&
usedMask
[
i1
])
continue
;
float
r1
=
0.5
f
*
keypoints1
[
i1
].
size
;
float
r1
=
0.5
f
*
keypoints1
[
i1
].
size
;
float
intersectRatio
=
calcIntersectRatio
(
points0t
.
at
<
Point2f
>
(
i0
),
r0
,
keypoints1
[
i1
].
pt
,
r1
);
if
(
intersectRatio
>
maxIntersectRatio
)
{
maxIntersectRatio
=
intersectRatio
;
nearestPointIndex
=
i1
;
maxIntersectRatio
=
intersectRatio
;
nearestPointIndex
=
i1
;
}
}
matches
.
push_back
(
DMatch
(
i0
,
nearestPointIndex
,
maxIntersectRatio
));
if
(
nearestPointIndex
>=
0
)
usedMask
[
nearestPointIndex
]
=
1
;
}
matches
.
push_back
(
DMatch
(
i0
,
nearestPointIndex
,
maxIntersectRatio
));
if
(
nearestPointIndex
>=
0
)
usedMask
[
nearestPointIndex
]
=
1
;
}
}
class
DetectorRotationInvarianceTest
:
public
cvtest
::
BaseTest
...
...
@@ -166,9 +192,9 @@ public:
DetectorRotationInvarianceTest
(
const
Ptr
<
FeatureDetector
>&
_featureDetector
,
float
_minKeyPointMatchesRatio
,
float
_minAngleInliersRatio
)
:
featureDetector
(
_featureDetector
),
minKeyPointMatchesRatio
(
_minKeyPointMatchesRatio
),
minAngleInliersRatio
(
_minAngleInliersRatio
)
featureDetector
(
_featureDetector
),
minKeyPointMatchesRatio
(
_minKeyPointMatchesRatio
),
minAngleInliersRatio
(
_minAngleInliersRatio
)
{
CV_Assert
(
!
featureDetector
.
empty
());
}
...
...
@@ -177,7 +203,7 @@ protected:
void
run
(
int
)
{
const
string
imageFilename
=
string
(
ts
->
get_data_path
())
+
IMAGE_TSUKUBA
;
const
string
imageFilename
=
string
(
ts
->
get_data_path
())
+
IMAGE_TSUKUBA
;
// Read test data
Mat
image0
=
imread
(
imageFilename
),
image1
,
mask1
;
...
...
@@ -191,7 +217,7 @@ protected:
vector
<
KeyPoint
>
keypoints0
;
featureDetector
->
detect
(
image0
,
keypoints0
);
if
(
keypoints0
.
size
()
<
15
)
CV_Error
(
CV_StsAssert
,
"Detector gives too few points in a test image
\n
"
);
CV_Error
(
CV_StsAssert
,
"Detector gives too few points in a test image
\n
"
);
const
int
maxAngle
=
360
,
angleStep
=
15
;
for
(
int
angle
=
0
;
angle
<
maxAngle
;
angle
+=
angleStep
)
...
...
@@ -201,23 +227,23 @@ protected:
vector
<
KeyPoint
>
keypoints1
;
featureDetector
->
detect
(
image1
,
keypoints1
,
mask1
);
vector
<
DMatch
>
matches
;
matchKeyPoints
(
keypoints0
,
H
,
keypoints1
,
matches
);
vector
<
DMatch
>
matches
;
matchKeyPoints
(
keypoints0
,
H
,
keypoints1
,
matches
);
int
angleInliersCount
=
0
;
const
float
minIntersectRatio
=
0.5
f
;
int
keyPointMatchesCount
=
0
;
const
float
minIntersectRatio
=
0.5
f
;
int
keyPointMatchesCount
=
0
;
for
(
size_t
m
=
0
;
m
<
matches
.
size
();
m
++
)
{
if
(
matches
[
m
].
distance
<
minIntersectRatio
)
continue
;
keyPointMatchesCount
++
;
if
(
matches
[
m
].
distance
<
minIntersectRatio
)
continue
;
keyPointMatchesCount
++
;
// Check does this inlier have consistent angles
// Check does this inlier have consistent angles
const
float
maxAngleDiff
=
15.
f
;
// grad
float
angle0
=
keypoints0
[
matches
[
m
].
queryIdx
].
angle
;
float
angle0
=
keypoints0
[
matches
[
m
].
queryIdx
].
angle
;
float
angle1
=
keypoints1
[
matches
[
m
].
trainIdx
].
angle
;
if
(
angle0
==
-
1
||
angle1
==
-
1
)
CV_Error
(
CV_StsBadArg
,
"Given FeatureDetector is not rotation invariant, it can not be tested here.
\n
"
);
...
...
@@ -230,13 +256,13 @@ protected:
float
angleDiff
=
std
::
max
(
rotAngle0
,
angle1
)
-
std
::
min
(
rotAngle0
,
angle1
);
angleDiff
=
std
::
min
(
angleDiff
,
static_cast
<
float
>
(
360.
f
-
angleDiff
));
CV_Assert
(
angleDiff
>=
0.
f
);
CV_Assert
(
angleDiff
>=
0.
f
);
bool
isAngleCorrect
=
angleDiff
<
maxAngleDiff
;
if
(
isAngleCorrect
)
angleInliersCount
++
;
}
float
keyPointMatchesRatio
=
static_cast
<
float
>
(
keyPointMatchesCount
)
/
keypoints0
.
size
();
float
keyPointMatchesRatio
=
static_cast
<
float
>
(
keyPointMatchesCount
)
/
keypoints0
.
size
();
if
(
keyPointMatchesRatio
<
minKeyPointMatchesRatio
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Incorrect keyPointMatchesRatio: curr = %f, min = %f.
\n
"
,
...
...
@@ -245,9 +271,9 @@ protected:
return
;
}
if
(
keyPointMatchesCount
)
if
(
keyPointMatchesCount
)
{
float
angleInliersRatio
=
static_cast
<
float
>
(
angleInliersCount
)
/
keyPointMatchesCount
;
float
angleInliersRatio
=
static_cast
<
float
>
(
angleInliersCount
)
/
keyPointMatchesCount
;
if
(
angleInliersRatio
<
minAngleInliersRatio
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Incorrect angleInliersRatio: curr = %f, min = %f.
\n
"
,
...
...
@@ -258,7 +284,7 @@ protected:
}
#if SHOW_DEBUG_LOG
std
::
cout
<<
"keyPointMatchesRatio - "
<<
keyPointMatchesRatio
<<
" - angleInliersRatio "
<<
static_cast
<
float
>
(
angleInliersCount
)
/
keyPointMatchesCount
<<
std
::
endl
;
<<
" - angleInliersRatio "
<<
static_cast
<
float
>
(
angleInliersCount
)
/
keyPointMatchesCount
<<
std
::
endl
;
#endif
}
ts
->
set_failed_test_info
(
cvtest
::
TS
::
OK
);
...
...
@@ -269,29 +295,20 @@ protected:
float
minAngleInliersRatio
;
};
void
scaleKeyPoints
(
const
vector
<
KeyPoint
>&
src
,
vector
<
KeyPoint
>&
dst
,
float
scale
)
{
dst
.
resize
(
src
.
size
());
for
(
size_t
i
=
0
;
i
<
src
.
size
();
i
++
)
dst
[
i
]
=
KeyPoint
(
src
[
i
].
pt
.
x
*
scale
,
src
[
i
].
pt
.
y
*
scale
,
src
[
i
].
size
*
scale
);
}
class
DescriptorRotationInvarianceTest
:
public
cvtest
::
BaseTest
{
public
:
DescriptorRotationInvarianceTest
(
const
Ptr
<
FeatureDetector
>&
_featureDetector
,
const
Ptr
<
DescriptorExtractor
>&
_descriptorExtractor
,
int
_normType
,
float
_minKeyPointMatchesRatio
,
float
_minDescInliersRatio
)
:
featureDetector
(
_featureDetector
),
descriptorExtractor
(
_descriptorExtractor
),
normType
(
_normType
),
minKeyPointMatchesRatio
(
_minKeyPointMatchesRatio
),
minDescInliersRatio
(
_minDescInliersRatio
)
const
Ptr
<
DescriptorExtractor
>&
_descriptorExtractor
,
int
_normType
,
float
_minDescInliersRatio
)
:
featureDetector
(
_featureDetector
),
descriptorExtractor
(
_descriptorExtractor
),
normType
(
_normType
),
minDescInliersRatio
(
_minDescInliersRatio
)
{
CV_Assert
(
!
featureDetector
.
empty
());
CV_Assert
(
!
descriptorExtractor
.
empty
());
CV_Assert
(
!
descriptorExtractor
.
empty
());
}
protected
:
...
...
@@ -310,80 +327,59 @@ protected:
}
vector
<
KeyPoint
>
keypoints0
;
Mat
descriptors0
;
Mat
descriptors0
;
featureDetector
->
detect
(
image0
,
keypoints0
);
if
(
keypoints0
.
size
()
<
15
)
CV_Error
(
CV_StsAssert
,
"Detector gives too few points in a test image
\n
"
);
descriptorExtractor
->
compute
(
image0
,
keypoints0
,
descriptors0
);
if
(
keypoints0
.
size
()
<
15
)
CV_Error
(
CV_StsAssert
,
"Detector gives too few points in a test image
\n
"
);
descriptorExtractor
->
compute
(
image0
,
keypoints0
,
descriptors0
);
BFMatcher
bfmatcher
(
normType
);
BFMatcher
bfmatcher
(
normType
);
const
float
minIntersectRatio
=
0.5
f
;
const
int
maxAngle
=
360
,
angleStep
=
15
;
for
(
int
angle
=
0
;
angle
<
maxAngle
;
angle
+=
angleStep
)
{
Mat
H
=
rotateImage
(
image0
,
angle
,
image1
,
mask1
);
vector
<
KeyPoint
>
keypoints1
;
Mat
descriptors1
;
featureDetector
->
detect
(
image1
,
keypoints1
,
mask1
);
descriptorExtractor
->
compute
(
image1
,
keypoints1
,
descriptors1
);
vector
<
DMatch
>
descMatches
;
bfmatcher
.
match
(
descriptors0
,
descriptors1
,
descMatches
);
vector
<
DMatch
>
keyPointMatches
;
matchKeyPoints
(
keypoints0
,
H
,
keypoints1
,
keyPointMatches
);
const
float
minIntersectRatio
=
0.5
f
;
int
keyPointMatchesCount
=
0
;
for
(
size_t
m
=
0
;
m
<
keyPointMatches
.
size
();
m
++
)
{
if
(
keyPointMatches
[
m
].
distance
>=
minIntersectRatio
)
keyPointMatchesCount
++
;
}
int
descInliersCount
=
0
;
for
(
size_t
m
=
0
;
m
<
descMatches
.
size
();
m
++
)
{
int
queryIdx
=
descMatches
[
m
].
queryIdx
;
if
(
keyPointMatches
[
queryIdx
].
distance
>=
minIntersectRatio
&&
descMatches
[
m
].
trainIdx
==
keyPointMatches
[
queryIdx
].
trainIdx
)
descInliersCount
++
;
}
rotateKeyPoints
(
keypoints0
,
H
,
angle
,
keypoints1
);
Mat
descriptors1
;
descriptorExtractor
->
compute
(
image1
,
keypoints1
,
descriptors1
);
float
keyPointMatchesRatio
=
static_cast
<
float
>
(
keyPointMatchesCount
)
/
keypoints0
.
size
();
if
(
keyPointMatchesRatio
<
minKeyPointMatchesRatio
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Incorrect keyPointMatchesRatio: curr = %f, min = %f.
\n
"
,
keyPointMatchesRatio
,
minKeyPointMatchesRatio
);
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_BAD_ACCURACY
);
return
;
}
vector
<
DMatch
>
descMatches
;
bfmatcher
.
match
(
descriptors0
,
descriptors1
,
descMatches
);
if
(
keyPointMatchesCount
)
int
descInliersCount
=
0
;
for
(
size_t
m
=
0
;
m
<
descMatches
.
size
();
m
++
)
{
float
descInliersRatio
=
static_cast
<
float
>
(
descInliersCount
)
/
keyPointMatchesCount
;
if
(
descInliersRatio
<
minDescInliersRatio
)
const
KeyPoint
&
transformed_p0
=
keypoints1
[
descMatches
[
m
].
queryIdx
];
const
KeyPoint
&
p1
=
keypoints1
[
descMatches
[
m
].
trainIdx
];
if
(
calcIntersectRatio
(
transformed_p0
.
pt
,
0.5
f
*
transformed_p0
.
size
,
p1
.
pt
,
0.5
f
*
p1
.
size
)
>=
minIntersectRatio
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Incorrect descInliersRatio: curr = %f, min = %f.
\n
"
,
descInliersRatio
,
minDescInliersRatio
);
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_BAD_ACCURACY
);
return
;
descInliersCount
++
;
}
}
float
descInliersRatio
=
static_cast
<
float
>
(
descInliersCount
)
/
keypoints0
.
size
();
if
(
descInliersRatio
<
minDescInliersRatio
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Incorrect descInliersRatio: curr = %f, min = %f.
\n
"
,
descInliersRatio
,
minDescInliersRatio
);
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_BAD_ACCURACY
);
return
;
}
#if SHOW_DEBUG_LOG
std
::
cout
<<
"keyPointMatchesRatio - "
<<
keyPointMatchesRatio
<<
" - descInliersRatio "
<<
static_cast
<
float
>
(
descInliersCount
)
/
keyPointMatchesCount
<<
std
::
endl
;
std
::
cout
<<
"descInliersRatio "
<<
static_cast
<
float
>
(
descInliersCount
)
/
keypoints0
.
size
()
<<
std
::
endl
;
#endif
}
ts
->
set_failed_test_info
(
cvtest
::
TS
::
OK
);
}
Ptr
<
FeatureDetector
>
featureDetector
;
Ptr
<
DescriptorExtractor
>
descriptorExtractor
;
Ptr
<
DescriptorExtractor
>
descriptorExtractor
;
int
normType
;
float
minKeyPointMatchesRatio
;
float
minDescInliersRatio
;
float
minDescInliersRatio
;
};
class
DetectorScaleInvarianceTest
:
public
cvtest
::
BaseTest
...
...
@@ -392,9 +388,9 @@ public:
DetectorScaleInvarianceTest
(
const
Ptr
<
FeatureDetector
>&
_featureDetector
,
float
_minKeyPointMatchesRatio
,
float
_minScaleInliersRatio
)
:
featureDetector
(
_featureDetector
),
minKeyPointMatchesRatio
(
_minKeyPointMatchesRatio
),
minScaleInliersRatio
(
_minScaleInliersRatio
)
featureDetector
(
_featureDetector
),
minKeyPointMatchesRatio
(
_minKeyPointMatchesRatio
),
minScaleInliersRatio
(
_minScaleInliersRatio
)
{
CV_Assert
(
!
featureDetector
.
empty
());
}
...
...
@@ -403,7 +399,7 @@ protected:
void
run
(
int
)
{
const
string
imageFilename
=
string
(
ts
->
get_data_path
())
+
IMAGE_BIKES
;
const
string
imageFilename
=
string
(
ts
->
get_data_path
())
+
IMAGE_BIKES
;
// Read test data
Mat
image0
=
imread
(
imageFilename
);
...
...
@@ -417,58 +413,59 @@ protected:
vector
<
KeyPoint
>
keypoints0
;
featureDetector
->
detect
(
image0
,
keypoints0
);
if
(
keypoints0
.
size
()
<
15
)
CV_Error
(
CV_StsAssert
,
"Detector gives too few points in a test image
\n
"
);
CV_Error
(
CV_StsAssert
,
"Detector gives too few points in a test image
\n
"
);
for
(
int
scale
=
2
;
scale
<=
4
;
scale
++
)
for
(
float
scaleIdx
=
1
;
scaleIdx
<=
3
;
scaleIdx
++
)
{
Mat
image1
;
resize
(
image0
,
image1
,
Size
(),
1.
/
scale
,
1.
/
scale
);
float
scale
=
1.
f
+
scaleIdx
*
0.5
f
;
Mat
image1
;
resize
(
image0
,
image1
,
Size
(),
1.
/
scale
,
1.
/
scale
);
vector
<
KeyPoint
>
keypoints1
,
osiKeypoints1
;
// osi - original size image
featureDetector
->
detect
(
image1
,
keypoints1
);
if
(
keypoints1
.
size
()
<
15
)
CV_Error
(
CV_StsAssert
,
"Detector gives too few points in a test image
\n
"
);
if
(
keypoints1
.
size
()
<
15
)
CV_Error
(
CV_StsAssert
,
"Detector gives too few points in a test image
\n
"
);
if
(
keypoints1
.
size
()
>
keypoints0
.
size
())
{
if
(
keypoints1
.
size
()
>
keypoints0
.
size
())
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Strange behavior of the detector. "
"It gives more points count in an image of the smaller size.
\n
"
"original size (%d, %d), keypoints count = %d
\n
"
"reduced size (%d, %d), keypoints count = %d
\n
"
,
image0
.
cols
,
image0
.
rows
,
keypoints0
.
size
(),
image1
.
cols
,
image1
.
rows
,
keypoints1
.
size
());
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_INVALID_OUTPUT
);
"It gives more points count in an image of the smaller size.
\n
"
"original size (%d, %d), keypoints count = %d
\n
"
"reduced size (%d, %d), keypoints count = %d
\n
"
,
image0
.
cols
,
image0
.
rows
,
keypoints0
.
size
(),
image1
.
cols
,
image1
.
rows
,
keypoints1
.
size
());
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_INVALID_OUTPUT
);
return
;
}
scaleKeyPoints
(
keypoints1
,
osiKeypoints1
,
scale
);
scaleKeyPoints
(
keypoints1
,
osiKeypoints1
,
scale
);
vector
<
DMatch
>
matches
;
// image1 is query image (it's reduced image0)
// image0 is train image
matchKeyPoints
(
osiKeypoints1
,
Mat
(),
keypoints0
,
matches
);
vector
<
DMatch
>
matches
;
// image1 is query image (it's reduced image0)
// image0 is train image
matchKeyPoints
(
osiKeypoints1
,
Mat
(),
keypoints0
,
matches
);
const
float
minIntersectRatio
=
0.5
f
;
int
keyPointMatchesCount
=
0
;
int
scaleInliersCount
=
0
;
const
float
minIntersectRatio
=
0.5
f
;
int
keyPointMatchesCount
=
0
;
int
scaleInliersCount
=
0
;
for
(
size_t
m
=
0
;
m
<
matches
.
size
();
m
++
)
for
(
size_t
m
=
0
;
m
<
matches
.
size
();
m
++
)
{
if
(
matches
[
m
].
distance
<
minIntersectRatio
)
continue
;
if
(
matches
[
m
].
distance
<
minIntersectRatio
)
continue
;
keyPointMatchesCount
++
;
keyPointMatchesCount
++
;
// Check does this inlier have consistent sizes
// Check does this inlier have consistent sizes
const
float
maxSizeDiff
=
0.8
;
//0.9f; // grad
float
size0
=
keypoints0
[
matches
[
m
].
trainIdx
].
size
;
float
size0
=
keypoints0
[
matches
[
m
].
trainIdx
].
size
;
float
size1
=
osiKeypoints1
[
matches
[
m
].
queryIdx
].
size
;
CV_Assert
(
size0
>
0
&&
size1
>
0
);
if
(
std
::
min
(
size0
,
size1
)
>
maxSizeDiff
*
std
::
max
(
size0
,
size1
))
CV_Assert
(
size0
>
0
&&
size1
>
0
);
if
(
std
::
min
(
size0
,
size1
)
>
maxSizeDiff
*
std
::
max
(
size0
,
size1
))
scaleInliersCount
++
;
}
float
keyPointMatchesRatio
=
static_cast
<
float
>
(
keyPointMatchesCount
)
/
keypoints1
.
size
();
float
keyPointMatchesRatio
=
static_cast
<
float
>
(
keyPointMatchesCount
)
/
keypoints1
.
size
();
if
(
keyPointMatchesRatio
<
minKeyPointMatchesRatio
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Incorrect keyPointMatchesRatio: curr = %f, min = %f.
\n
"
,
...
...
@@ -477,9 +474,9 @@ protected:
return
;
}
if
(
keyPointMatchesCount
)
if
(
keyPointMatchesCount
)
{
float
scaleInliersRatio
=
static_cast
<
float
>
(
scaleInliersCount
)
/
keyPointMatchesCount
;
float
scaleInliersRatio
=
static_cast
<
float
>
(
scaleInliersCount
)
/
keyPointMatchesCount
;
if
(
scaleInliersRatio
<
minScaleInliersRatio
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Incorrect scaleInliersRatio: curr = %f, min = %f.
\n
"
,
...
...
@@ -490,21 +487,8 @@ protected:
}
#if SHOW_DEBUG_LOG
std
::
cout
<<
"keyPointMatchesRatio - "
<<
keyPointMatchesRatio
<<
" - scaleInliersRatio "
<<
static_cast
<
float
>
(
scaleInliersCount
)
/
keyPointMatchesCount
<<
std
::
endl
;
<<
" - scaleInliersRatio "
<<
static_cast
<
float
>
(
scaleInliersCount
)
/
keyPointMatchesCount
<<
std
::
endl
;
#endif
/*vector<DMatch> filteredMatches;
for(size_t i = 0; i < matches.size(); i++)
{
if(matches[i].distance >= minIntersectRatio)
filteredMatches.push_back(matches[i]);
}
Mat out;
namedWindow("out", CV_WINDOW_NORMAL);
drawMatches(image1, keypoints1, image0, keypoints0, filteredMatches, out,
Scalar::all(-1), Scalar(-1), vector<char>(), DrawMatchesFlags::DEFAULT + DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
imshow("out", out);
waitKey();*/
}
ts
->
set_failed_test_info
(
cvtest
::
TS
::
OK
);
}
...
...
@@ -518,25 +502,23 @@ class DescriptorScaleInvarianceTest : public cvtest::BaseTest
{
public
:
DescriptorScaleInvarianceTest
(
const
Ptr
<
FeatureDetector
>&
_featureDetector
,
const
Ptr
<
DescriptorExtractor
>&
_descriptorExtractor
,
int
_normType
,
float
_minKeyPointMatchesRatio
,
const
Ptr
<
DescriptorExtractor
>&
_descriptorExtractor
,
int
_normType
,
float
_minDescInliersRatio
)
:
featureDetector
(
_featureDetector
),
descriptorExtractor
(
_descriptorExtractor
),
normType
(
_normType
),
minKeyPointMatchesRatio
(
_minKeyPointMatchesRatio
),
minDescInliersRatio
(
_minDescInliersRatio
)
featureDetector
(
_featureDetector
),
descriptorExtractor
(
_descriptorExtractor
),
normType
(
_normType
),
minDescInliersRatio
(
_minDescInliersRatio
)
{
CV_Assert
(
!
featureDetector
.
empty
());
CV_Assert
(
!
descriptorExtractor
.
empty
());
CV_Assert
(
!
descriptorExtractor
.
empty
());
}
protected
:
void
run
(
int
)
{
const
string
imageFilename
=
string
(
ts
->
get_data_path
())
+
IMAGE_BIKES
;
const
string
imageFilename
=
string
(
ts
->
get_data_path
())
+
IMAGE_BIKES
;
// Read test data
Mat
image0
=
imread
(
imageFilename
);
...
...
@@ -549,145 +531,126 @@ protected:
vector
<
KeyPoint
>
keypoints0
;
featureDetector
->
detect
(
image0
,
keypoints0
);
if
(
keypoints0
.
size
()
<
15
)
CV_Error
(
CV_StsAssert
,
"Detector gives too few points in a test image
\n
"
);
Mat
descriptors0
;
descriptorExtractor
->
compute
(
image0
,
keypoints0
,
descriptors0
);
if
(
keypoints0
.
size
()
<
15
)
CV_Error
(
CV_StsAssert
,
"Detector gives too few points in a test image
\n
"
);
Mat
descriptors0
;
descriptorExtractor
->
compute
(
image0
,
keypoints0
,
descriptors0
);
BFMatcher
bfmatcher
(
normType
);
for
(
int
scale
=
2
;
scale
<=
4
;
scale
++
)
BFMatcher
bfmatcher
(
normType
);
for
(
float
scaleIdx
=
1
;
scaleIdx
<=
3
;
scaleIdx
++
)
{
Mat
image1
;
resize
(
image0
,
image1
,
Size
(),
1.
/
scale
,
1.
/
scale
);
float
scale
=
1.
f
+
scaleIdx
*
0.5
f
;
vector
<
KeyPoint
>
keypoints1
,
osiKeypoints1
;
// osi - original size image
featureDetector
->
detect
(
image1
,
keypoints1
);
if
(
keypoints1
.
size
()
<
15
)
CV_Error
(
CV_StsAssert
,
"Detector gives too few points in a test image
\n
"
);
if
(
keypoints1
.
size
()
>
keypoints0
.
size
()
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Strange behavior of the detector. "
"It gives more points count in an image of the smaller size.
\n
"
"original size (%d, %d), keypoints count = %d
\n
"
"reduced size (%d, %d), keypoints count = %d
\n
"
,
image0
.
cols
,
image0
.
rows
,
keypoints0
.
size
(),
image1
.
cols
,
image1
.
rows
,
keypoints1
.
size
());
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_INVALID_OUTPUT
);
return
;
}
Mat
image1
;
resize
(
image0
,
image1
,
Size
(),
1.
/
scale
,
1.
/
scale
);
Mat
descriptors1
;
descriptorExtractor
->
compute
(
image1
,
keypoints1
,
descriptors1
);
vector
<
DMatch
>
keyPointMatches
,
descMatches
;
// image1 is query image (it's reduced image0)
// image0 is train image
bfmatcher
.
match
(
descriptors1
,
descriptors0
,
descMatches
);
scaleKeyPoints
(
keypoints1
,
osiKeypoints1
,
scale
);
matchKeyPoints
(
osiKeypoints1
,
Mat
(),
keypoints0
,
keyPointMatches
);
const
float
minIntersectRatio
=
0.5
f
;
int
keyPointMatchesCount
=
0
;
for
(
size_t
m
=
0
;
m
<
keyPointMatches
.
size
();
m
++
)
{
if
(
keyPointMatches
[
m
].
distance
>=
minIntersectRatio
)
keyPointMatchesCount
++
;
}
int
descInliersCount
=
0
;
for
(
size_t
m
=
0
;
m
<
descMatches
.
size
();
m
++
)
{
int
queryIdx
=
descMatches
[
m
].
queryIdx
;
if
(
keyPointMatches
[
queryIdx
].
distance
>=
minIntersectRatio
&&
descMatches
[
m
].
trainIdx
==
keyPointMatches
[
queryIdx
].
trainIdx
)
descInliersCount
++
;
}
vector
<
KeyPoint
>
keypoints1
;
scaleKeyPoints
(
keypoints0
,
keypoints1
,
1.
/
scale
);
Mat
descriptors1
;
descriptorExtractor
->
compute
(
image1
,
keypoints1
,
descriptors1
);
float
keyPointMatchesRatio
=
static_cast
<
float
>
(
keyPointMatchesCount
)
/
keypoints1
.
size
();
if
(
keyPointMatchesRatio
<
minKeyPointMatchesRatio
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Incorrect keyPointMatchesRatio: curr = %f, min = %f.
\n
"
,
keyPointMatchesRatio
,
minKeyPointMatchesRatio
);
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_BAD_ACCURACY
);
return
;
}
vector
<
DMatch
>
descMatches
;
bfmatcher
.
match
(
descriptors0
,
descriptors1
,
descMatches
);
if
(
keyPointMatchesCount
)
const
float
minIntersectRatio
=
0.5
f
;
int
descInliersCount
=
0
;
for
(
size_t
m
=
0
;
m
<
descMatches
.
size
();
m
++
)
{
float
descInliersRatio
=
static_cast
<
float
>
(
descInliersCount
)
/
keyPointMatchesCount
;
if
(
descInliersRatio
<
minDescInliersRatio
)
const
KeyPoint
&
transformed_p0
=
keypoints0
[
descMatches
[
m
].
queryIdx
];
const
KeyPoint
&
p1
=
keypoints0
[
descMatches
[
m
].
trainIdx
];
if
(
calcIntersectRatio
(
transformed_p0
.
pt
,
0.5
f
*
transformed_p0
.
size
,
p1
.
pt
,
0.5
f
*
p1
.
size
)
>=
minIntersectRatio
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Incorrect descInliersRatio: curr = %f, min = %f.
\n
"
,
descInliersRatio
,
minDescInliersRatio
);
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_BAD_ACCURACY
);
return
;
descInliersCount
++
;
}
}
float
descInliersRatio
=
static_cast
<
float
>
(
descInliersCount
)
/
keypoints0
.
size
();
if
(
descInliersRatio
<
minDescInliersRatio
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Incorrect descInliersRatio: curr = %f, min = %f.
\n
"
,
descInliersRatio
,
minDescInliersRatio
);
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_BAD_ACCURACY
);
return
;
}
#if SHOW_DEBUG_LOG
std
::
cout
<<
"keyPointMatchesRatio - "
<<
keyPointMatchesRatio
<<
" - descInliersRatio "
<<
static_cast
<
float
>
(
descInliersCount
)
/
keyPointMatchesCount
<<
std
::
endl
;
std
::
cout
<<
"descInliersRatio "
<<
static_cast
<
float
>
(
descInliersCount
)
/
keypoints0
.
size
()
<<
std
::
endl
;
#endif
}
ts
->
set_failed_test_info
(
cvtest
::
TS
::
OK
);
}
Ptr
<
FeatureDetector
>
featureDetector
;
Ptr
<
DescriptorExtractor
>
descriptorExtractor
;
int
normType
;
Ptr
<
DescriptorExtractor
>
descriptorExtractor
;
int
normType
;
float
minKeyPointMatchesRatio
;
float
minDescInliersRatio
;
};
// Tests registration
// Detector's rotation invariance check
/*
* Detector's rotation invariance check
*/
TEST
(
Features2d_RotationInvariance_Detector_ORB
,
regression
)
{
DetectorRotationInvarianceTest
test
(
Algorithm
::
create
<
FeatureDetector
>
(
"Feature2D.ORB"
),
0.45
f
,
0.75
f
);
0.47
f
,
0.77
f
);
test
.
safe_run
();
}
// Descriptors's rotation invariance check
/*
* Descriptors's rotation invariance check
*/
TEST
(
Features2d_RotationInvariance_Descriptor_ORB
,
regression
)
{
DescriptorRotationInvarianceTest
test
(
Algorithm
::
create
<
FeatureDetector
>
(
"Feature2D.ORB"
),
Algorithm
::
create
<
DescriptorExtractor
>
(
"Feature2D.ORB"
),
NORM_HAMMING
,
0.45
f
,
0.53
f
);
0.99
f
);
test
.
safe_run
();
}
// TODO: Uncomment test for FREAK when it will work; add test for scale invariance for FREAK
//TEST(Features2d_RotationInvariance_Descriptor_FREAK, regression)
//{
// DescriptorRotationInvarianceTest test(Algorithm::create<FeatureDetector>("Feature2D.ORB"),
// Algorithm::create<DescriptorExtractor>("Feature2D.FREAK"),
// NORM_HAMMING(?),
// 0.45f,
// 0.?f);
// DescriptorRotationInvarianceTest test(Algorithm::create<FeatureDetector>("Feature2D.ORB"),
// Algorithm::create<DescriptorExtractor>("Feature2D.FREAK"),
// NORM_HAMMING,
// 0.f);
// test.safe_run();
//}
/* TODO: Why ORB has bad scale invariance in this tests?
// Detector's scale invariance check
TEST(Features2d_ScaleInvariance_Detector_ORB, regression)
{
DetectorScaleInvarianceTest test(Algorithm::create<FeatureDetector>("Feature2D.ORB"),
0.13f,
0.0f);
test.safe_run();
}
/*
* Detector's scale invariance check
*/
// Descriptor's scale invariance check
TEST(Features2d_ScaleInvariance_Descriptor_ORB, regression)
{
DescriptorScaleInvarianceTest test(Algorithm::create<FeatureDetector>("Feature2D.ORB"),
Algorithm::create<DescriptorExtractor>("Feature2D.ORB"),
NORM_HAMMING,
0.13f,
0.36f);
test.safe_run();
}*/
\ No newline at end of file
//TEST(Features2d_ScaleInvariance_Detector_ORB, regression)
//{
// DetectorScaleInvarianceTest test(Algorithm::create<FeatureDetector>("Feature2D.ORB"),
// 0.22f,
// 0.83f);
// test.safe_run();
//}
/*
* Descriptor's scale invariance check
*/
//TEST(Features2d_ScaleInvariance_Descriptor_ORB, regression)
//{
// DescriptorScaleInvarianceTest test(Algorithm::create<FeatureDetector>("Feature2D.ORB"),
// Algorithm::create<DescriptorExtractor>("Feature2D.ORB"),
// NORM_HAMMING,
// 0.01f);
// test.safe_run();
//}
//TEST(Features2d_ScaleInvariance_Descriptor_FREAK, regression)
//{
// DescriptorScaleInvarianceTest test(Algorithm::create<FeatureDetector>("Feature2D.ORB"),
// Algorithm::create<DescriptorExtractor>("Feature2D.FREAK"),
// NORM_HAMMING,
// 0.01f);
// test.safe_run();
//}
modules/nonfree/test/test_rotation_and_scale_invariance.cpp
View file @
2556bb04
...
...
@@ -53,7 +53,7 @@ const string IMAGE_BIKES = "/detectors_descriptors_evaluation/images_datasets/bi
static
Mat
generateHomography
(
float
angle
)
{
// angle - rotation around Oz in degrees
// angle - rotation around Oz in degrees
float
angleRadian
=
angle
*
CV_PI
/
180.
;
Mat
H
=
Mat
::
eye
(
3
,
3
,
CV_32FC1
);
H
.
at
<
float
>
(
0
,
0
)
=
H
.
at
<
float
>
(
1
,
1
)
=
std
::
cos
(
angleRadian
);
...
...
@@ -66,7 +66,7 @@ Mat generateHomography(float angle)
static
Mat
rotateImage
(
const
Mat
&
srcImage
,
float
angle
,
Mat
&
dstImage
,
Mat
&
dstMask
)
{
// angle - rotation around Oz in degrees
// angle - rotation around Oz in degrees
float
diag
=
std
::
sqrt
(
static_cast
<
float
>
(
srcImage
.
cols
*
srcImage
.
cols
+
srcImage
.
rows
*
srcImage
.
rows
));
Mat
LUShift
=
Mat
::
eye
(
3
,
3
,
CV_32FC1
);
// left up
LUShift
.
at
<
float
>
(
0
,
2
)
=
-
srcImage
.
cols
/
2
;
...
...
@@ -85,6 +85,32 @@ Mat rotateImage(const Mat& srcImage, float angle, Mat& dstImage, Mat& dstMask)
return
H
;
}
void
rotateKeyPoints
(
const
vector
<
KeyPoint
>&
src
,
const
Mat
&
H
,
float
angle
,
vector
<
KeyPoint
>&
dst
)
{
// suppose that H is rotation given from rotateImage() and angle has value passed to rotateImage()
vector
<
Point2f
>
srcCenters
,
dstCenters
;
KeyPoint
::
convert
(
src
,
srcCenters
);
perspectiveTransform
(
srcCenters
,
dstCenters
,
H
);
dst
=
src
;
for
(
size_t
i
=
0
;
i
<
dst
.
size
();
i
++
)
{
dst
[
i
].
pt
=
dstCenters
[
i
];
float
dstAngle
=
src
[
i
].
angle
+
angle
;
if
(
dstAngle
>=
360.
f
)
dstAngle
-=
360.
f
;
dst
[
i
].
angle
=
dstAngle
;
}
}
void
scaleKeyPoints
(
const
vector
<
KeyPoint
>&
src
,
vector
<
KeyPoint
>&
dst
,
float
scale
)
{
dst
.
resize
(
src
.
size
());
for
(
size_t
i
=
0
;
i
<
src
.
size
();
i
++
)
dst
[
i
]
=
KeyPoint
(
src
[
i
].
pt
.
x
*
scale
,
src
[
i
].
pt
.
y
*
scale
,
src
[
i
].
size
*
scale
);
}
static
float
calcCirclesIntersectArea
(
const
Point2f
&
p0
,
float
r0
,
const
Point2f
&
p1
,
float
r1
)
{
...
...
@@ -119,45 +145,45 @@ float calcIntersectRatio(const Point2f& p0, float r0, const Point2f& p1, float r
return
intersectArea
/
unionArea
;
}
static
static
void
matchKeyPoints
(
const
vector
<
KeyPoint
>&
keypoints0
,
const
Mat
&
H
,
const
vector
<
KeyPoint
>&
keypoints1
,
vector
<
DMatch
>&
matches
)
const
vector
<
KeyPoint
>&
keypoints1
,
vector
<
DMatch
>&
matches
)
{
vector
<
Point2f
>
points0
;
vector
<
Point2f
>
points0
;
KeyPoint
::
convert
(
keypoints0
,
points0
);
Mat
points0t
;
if
(
H
.
empty
())
points0t
=
Mat
(
points0
);
else
perspectiveTransform
(
Mat
(
points0
),
points0t
,
H
);
matches
.
clear
();
vector
<
uchar
>
usedMask
(
keypoints1
.
size
(),
0
);
for
(
size_t
i0
=
0
;
i0
<
keypoints0
.
size
();
i0
++
)
{
int
nearestPointIndex
=
-
1
;
if
(
H
.
empty
())
points0t
=
Mat
(
points0
);
else
perspectiveTransform
(
Mat
(
points0
),
points0t
,
H
);
matches
.
clear
();
vector
<
uchar
>
usedMask
(
keypoints1
.
size
(),
0
);
for
(
size_t
i0
=
0
;
i0
<
keypoints0
.
size
();
i0
++
)
{
int
nearestPointIndex
=
-
1
;
float
maxIntersectRatio
=
0.
f
;
const
float
r0
=
0.5
f
*
keypoints0
[
i0
].
size
;
for
(
size_t
i1
=
0
;
i1
<
keypoints1
.
size
();
i1
++
)
{
if
(
nearestPointIndex
>=
0
&&
usedMask
[
i1
])
continue
;
if
(
nearestPointIndex
>=
0
&&
usedMask
[
i1
])
continue
;
float
r1
=
0.5
f
*
keypoints1
[
i1
].
size
;
float
r1
=
0.5
f
*
keypoints1
[
i1
].
size
;
float
intersectRatio
=
calcIntersectRatio
(
points0t
.
at
<
Point2f
>
(
i0
),
r0
,
keypoints1
[
i1
].
pt
,
r1
);
if
(
intersectRatio
>
maxIntersectRatio
)
{
maxIntersectRatio
=
intersectRatio
;
nearestPointIndex
=
i1
;
maxIntersectRatio
=
intersectRatio
;
nearestPointIndex
=
i1
;
}
}
matches
.
push_back
(
DMatch
(
i0
,
nearestPointIndex
,
maxIntersectRatio
));
if
(
nearestPointIndex
>=
0
)
usedMask
[
nearestPointIndex
]
=
1
;
}
matches
.
push_back
(
DMatch
(
i0
,
nearestPointIndex
,
maxIntersectRatio
));
if
(
nearestPointIndex
>=
0
)
usedMask
[
nearestPointIndex
]
=
1
;
}
}
class
DetectorRotationInvarianceTest
:
public
cvtest
::
BaseTest
...
...
@@ -166,9 +192,9 @@ public:
DetectorRotationInvarianceTest
(
const
Ptr
<
FeatureDetector
>&
_featureDetector
,
float
_minKeyPointMatchesRatio
,
float
_minAngleInliersRatio
)
:
featureDetector
(
_featureDetector
),
minKeyPointMatchesRatio
(
_minKeyPointMatchesRatio
),
minAngleInliersRatio
(
_minAngleInliersRatio
)
featureDetector
(
_featureDetector
),
minKeyPointMatchesRatio
(
_minKeyPointMatchesRatio
),
minAngleInliersRatio
(
_minAngleInliersRatio
)
{
CV_Assert
(
!
featureDetector
.
empty
());
}
...
...
@@ -177,7 +203,7 @@ protected:
void
run
(
int
)
{
const
string
imageFilename
=
string
(
ts
->
get_data_path
())
+
IMAGE_TSUKUBA
;
const
string
imageFilename
=
string
(
ts
->
get_data_path
())
+
IMAGE_TSUKUBA
;
// Read test data
Mat
image0
=
imread
(
imageFilename
),
image1
,
mask1
;
...
...
@@ -191,7 +217,7 @@ protected:
vector
<
KeyPoint
>
keypoints0
;
featureDetector
->
detect
(
image0
,
keypoints0
);
if
(
keypoints0
.
size
()
<
15
)
CV_Error
(
CV_StsAssert
,
"Detector gives too few points in a test image
\n
"
);
CV_Error
(
CV_StsAssert
,
"Detector gives too few points in a test image
\n
"
);
const
int
maxAngle
=
360
,
angleStep
=
15
;
for
(
int
angle
=
0
;
angle
<
maxAngle
;
angle
+=
angleStep
)
...
...
@@ -201,23 +227,23 @@ protected:
vector
<
KeyPoint
>
keypoints1
;
featureDetector
->
detect
(
image1
,
keypoints1
,
mask1
);
vector
<
DMatch
>
matches
;
matchKeyPoints
(
keypoints0
,
H
,
keypoints1
,
matches
);
vector
<
DMatch
>
matches
;
matchKeyPoints
(
keypoints0
,
H
,
keypoints1
,
matches
);
int
angleInliersCount
=
0
;
const
float
minIntersectRatio
=
0.5
f
;
int
keyPointMatchesCount
=
0
;
const
float
minIntersectRatio
=
0.5
f
;
int
keyPointMatchesCount
=
0
;
for
(
size_t
m
=
0
;
m
<
matches
.
size
();
m
++
)
{
if
(
matches
[
m
].
distance
<
minIntersectRatio
)
continue
;
keyPointMatchesCount
++
;
if
(
matches
[
m
].
distance
<
minIntersectRatio
)
continue
;
keyPointMatchesCount
++
;
// Check does this inlier have consistent angles
// Check does this inlier have consistent angles
const
float
maxAngleDiff
=
15.
f
;
// grad
float
angle0
=
keypoints0
[
matches
[
m
].
queryIdx
].
angle
;
float
angle0
=
keypoints0
[
matches
[
m
].
queryIdx
].
angle
;
float
angle1
=
keypoints1
[
matches
[
m
].
trainIdx
].
angle
;
if
(
angle0
==
-
1
||
angle1
==
-
1
)
CV_Error
(
CV_StsBadArg
,
"Given FeatureDetector is not rotation invariant, it can not be tested here.
\n
"
);
...
...
@@ -230,13 +256,13 @@ protected:
float
angleDiff
=
std
::
max
(
rotAngle0
,
angle1
)
-
std
::
min
(
rotAngle0
,
angle1
);
angleDiff
=
std
::
min
(
angleDiff
,
static_cast
<
float
>
(
360.
f
-
angleDiff
));
CV_Assert
(
angleDiff
>=
0.
f
);
CV_Assert
(
angleDiff
>=
0.
f
);
bool
isAngleCorrect
=
angleDiff
<
maxAngleDiff
;
if
(
isAngleCorrect
)
angleInliersCount
++
;
}
float
keyPointMatchesRatio
=
static_cast
<
float
>
(
keyPointMatchesCount
)
/
keypoints0
.
size
();
float
keyPointMatchesRatio
=
static_cast
<
float
>
(
keyPointMatchesCount
)
/
keypoints0
.
size
();
if
(
keyPointMatchesRatio
<
minKeyPointMatchesRatio
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Incorrect keyPointMatchesRatio: curr = %f, min = %f.
\n
"
,
...
...
@@ -245,9 +271,9 @@ protected:
return
;
}
if
(
keyPointMatchesCount
)
if
(
keyPointMatchesCount
)
{
float
angleInliersRatio
=
static_cast
<
float
>
(
angleInliersCount
)
/
keyPointMatchesCount
;
float
angleInliersRatio
=
static_cast
<
float
>
(
angleInliersCount
)
/
keyPointMatchesCount
;
if
(
angleInliersRatio
<
minAngleInliersRatio
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Incorrect angleInliersRatio: curr = %f, min = %f.
\n
"
,
...
...
@@ -258,7 +284,7 @@ protected:
}
#if SHOW_DEBUG_LOG
std
::
cout
<<
"keyPointMatchesRatio - "
<<
keyPointMatchesRatio
<<
" - angleInliersRatio "
<<
static_cast
<
float
>
(
angleInliersCount
)
/
keyPointMatchesCount
<<
std
::
endl
;
<<
" - angleInliersRatio "
<<
static_cast
<
float
>
(
angleInliersCount
)
/
keyPointMatchesCount
<<
std
::
endl
;
#endif
}
ts
->
set_failed_test_info
(
cvtest
::
TS
::
OK
);
...
...
@@ -269,29 +295,20 @@ protected:
float
minAngleInliersRatio
;
};
void
scaleKeyPoints
(
const
vector
<
KeyPoint
>&
src
,
vector
<
KeyPoint
>&
dst
,
float
scale
)
{
dst
.
resize
(
src
.
size
());
for
(
size_t
i
=
0
;
i
<
src
.
size
();
i
++
)
dst
[
i
]
=
KeyPoint
(
src
[
i
].
pt
.
x
*
scale
,
src
[
i
].
pt
.
y
*
scale
,
src
[
i
].
size
*
scale
);
}
class
DescriptorRotationInvarianceTest
:
public
cvtest
::
BaseTest
{
public
:
DescriptorRotationInvarianceTest
(
const
Ptr
<
FeatureDetector
>&
_featureDetector
,
const
Ptr
<
DescriptorExtractor
>&
_descriptorExtractor
,
int
_normType
,
float
_minKeyPointMatchesRatio
,
float
_minDescInliersRatio
)
:
featureDetector
(
_featureDetector
),
descriptorExtractor
(
_descriptorExtractor
),
normType
(
_normType
),
minKeyPointMatchesRatio
(
_minKeyPointMatchesRatio
),
minDescInliersRatio
(
_minDescInliersRatio
)
const
Ptr
<
DescriptorExtractor
>&
_descriptorExtractor
,
int
_normType
,
float
_minDescInliersRatio
)
:
featureDetector
(
_featureDetector
),
descriptorExtractor
(
_descriptorExtractor
),
normType
(
_normType
),
minDescInliersRatio
(
_minDescInliersRatio
)
{
CV_Assert
(
!
featureDetector
.
empty
());
CV_Assert
(
!
descriptorExtractor
.
empty
());
CV_Assert
(
!
descriptorExtractor
.
empty
());
}
protected
:
...
...
@@ -310,80 +327,59 @@ protected:
}
vector
<
KeyPoint
>
keypoints0
;
Mat
descriptors0
;
Mat
descriptors0
;
featureDetector
->
detect
(
image0
,
keypoints0
);
if
(
keypoints0
.
size
()
<
15
)
CV_Error
(
CV_StsAssert
,
"Detector gives too few points in a test image
\n
"
);
descriptorExtractor
->
compute
(
image0
,
keypoints0
,
descriptors0
);
if
(
keypoints0
.
size
()
<
15
)
CV_Error
(
CV_StsAssert
,
"Detector gives too few points in a test image
\n
"
);
descriptorExtractor
->
compute
(
image0
,
keypoints0
,
descriptors0
);
BFMatcher
bfmatcher
(
normType
);
BFMatcher
bfmatcher
(
normType
);
const
float
minIntersectRatio
=
0.5
f
;
const
int
maxAngle
=
360
,
angleStep
=
15
;
for
(
int
angle
=
0
;
angle
<
maxAngle
;
angle
+=
angleStep
)
{
Mat
H
=
rotateImage
(
image0
,
angle
,
image1
,
mask1
);
vector
<
KeyPoint
>
keypoints1
;
Mat
descriptors1
;
featureDetector
->
detect
(
image1
,
keypoints1
,
mask1
);
descriptorExtractor
->
compute
(
image1
,
keypoints1
,
descriptors1
);
vector
<
DMatch
>
descMatches
;
bfmatcher
.
match
(
descriptors0
,
descriptors1
,
descMatches
);
vector
<
DMatch
>
keyPointMatches
;
matchKeyPoints
(
keypoints0
,
H
,
keypoints1
,
keyPointMatches
);
const
float
minIntersectRatio
=
0.5
f
;
int
keyPointMatchesCount
=
0
;
for
(
size_t
m
=
0
;
m
<
keyPointMatches
.
size
();
m
++
)
{
if
(
keyPointMatches
[
m
].
distance
>=
minIntersectRatio
)
keyPointMatchesCount
++
;
}
int
descInliersCount
=
0
;
for
(
size_t
m
=
0
;
m
<
descMatches
.
size
();
m
++
)
{
int
queryIdx
=
descMatches
[
m
].
queryIdx
;
if
(
keyPointMatches
[
queryIdx
].
distance
>=
minIntersectRatio
&&
descMatches
[
m
].
trainIdx
==
keyPointMatches
[
queryIdx
].
trainIdx
)
descInliersCount
++
;
}
rotateKeyPoints
(
keypoints0
,
H
,
angle
,
keypoints1
);
Mat
descriptors1
;
descriptorExtractor
->
compute
(
image1
,
keypoints1
,
descriptors1
);
float
keyPointMatchesRatio
=
static_cast
<
float
>
(
keyPointMatchesCount
)
/
keypoints0
.
size
();
if
(
keyPointMatchesRatio
<
minKeyPointMatchesRatio
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Incorrect keyPointMatchesRatio: curr = %f, min = %f.
\n
"
,
keyPointMatchesRatio
,
minKeyPointMatchesRatio
);
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_BAD_ACCURACY
);
return
;
}
vector
<
DMatch
>
descMatches
;
bfmatcher
.
match
(
descriptors0
,
descriptors1
,
descMatches
);
if
(
keyPointMatchesCount
)
int
descInliersCount
=
0
;
for
(
size_t
m
=
0
;
m
<
descMatches
.
size
();
m
++
)
{
float
descInliersRatio
=
static_cast
<
float
>
(
descInliersCount
)
/
keyPointMatchesCount
;
if
(
descInliersRatio
<
minDescInliersRatio
)
const
KeyPoint
&
transformed_p0
=
keypoints1
[
descMatches
[
m
].
queryIdx
];
const
KeyPoint
&
p1
=
keypoints1
[
descMatches
[
m
].
trainIdx
];
if
(
calcIntersectRatio
(
transformed_p0
.
pt
,
0.5
f
*
transformed_p0
.
size
,
p1
.
pt
,
0.5
f
*
p1
.
size
)
>=
minIntersectRatio
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Incorrect descInliersRatio: curr = %f, min = %f.
\n
"
,
descInliersRatio
,
minDescInliersRatio
);
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_BAD_ACCURACY
);
return
;
descInliersCount
++
;
}
}
float
descInliersRatio
=
static_cast
<
float
>
(
descInliersCount
)
/
keypoints0
.
size
();
if
(
descInliersRatio
<
minDescInliersRatio
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Incorrect descInliersRatio: curr = %f, min = %f.
\n
"
,
descInliersRatio
,
minDescInliersRatio
);
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_BAD_ACCURACY
);
return
;
}
#if SHOW_DEBUG_LOG
std
::
cout
<<
"keyPointMatchesRatio - "
<<
keyPointMatchesRatio
<<
" - descInliersRatio "
<<
static_cast
<
float
>
(
descInliersCount
)
/
keyPointMatchesCount
<<
std
::
endl
;
std
::
cout
<<
"descInliersRatio "
<<
static_cast
<
float
>
(
descInliersCount
)
/
keypoints0
.
size
()
<<
std
::
endl
;
#endif
}
ts
->
set_failed_test_info
(
cvtest
::
TS
::
OK
);
}
Ptr
<
FeatureDetector
>
featureDetector
;
Ptr
<
DescriptorExtractor
>
descriptorExtractor
;
Ptr
<
DescriptorExtractor
>
descriptorExtractor
;
int
normType
;
float
minKeyPointMatchesRatio
;
float
minDescInliersRatio
;
float
minDescInliersRatio
;
};
class
DetectorScaleInvarianceTest
:
public
cvtest
::
BaseTest
...
...
@@ -392,9 +388,9 @@ public:
DetectorScaleInvarianceTest
(
const
Ptr
<
FeatureDetector
>&
_featureDetector
,
float
_minKeyPointMatchesRatio
,
float
_minScaleInliersRatio
)
:
featureDetector
(
_featureDetector
),
minKeyPointMatchesRatio
(
_minKeyPointMatchesRatio
),
minScaleInliersRatio
(
_minScaleInliersRatio
)
featureDetector
(
_featureDetector
),
minKeyPointMatchesRatio
(
_minKeyPointMatchesRatio
),
minScaleInliersRatio
(
_minScaleInliersRatio
)
{
CV_Assert
(
!
featureDetector
.
empty
());
}
...
...
@@ -403,7 +399,7 @@ protected:
void
run
(
int
)
{
const
string
imageFilename
=
string
(
ts
->
get_data_path
())
+
IMAGE_BIKES
;
const
string
imageFilename
=
string
(
ts
->
get_data_path
())
+
IMAGE_BIKES
;
// Read test data
Mat
image0
=
imread
(
imageFilename
);
...
...
@@ -417,58 +413,59 @@ protected:
vector
<
KeyPoint
>
keypoints0
;
featureDetector
->
detect
(
image0
,
keypoints0
);
if
(
keypoints0
.
size
()
<
15
)
CV_Error
(
CV_StsAssert
,
"Detector gives too few points in a test image
\n
"
);
CV_Error
(
CV_StsAssert
,
"Detector gives too few points in a test image
\n
"
);
for
(
int
scale
=
2
;
scale
<=
4
;
scale
++
)
for
(
float
scaleIdx
=
1
;
scaleIdx
<=
3
;
scaleIdx
++
)
{
Mat
image1
;
resize
(
image0
,
image1
,
Size
(),
1.
/
scale
,
1.
/
scale
);
float
scale
=
1.
f
+
scaleIdx
*
0.5
f
;
Mat
image1
;
resize
(
image0
,
image1
,
Size
(),
1.
/
scale
,
1.
/
scale
);
vector
<
KeyPoint
>
keypoints1
,
osiKeypoints1
;
// osi - original size image
featureDetector
->
detect
(
image1
,
keypoints1
);
if
(
keypoints1
.
size
()
<
15
)
CV_Error
(
CV_StsAssert
,
"Detector gives too few points in a test image
\n
"
);
if
(
keypoints1
.
size
()
<
15
)
CV_Error
(
CV_StsAssert
,
"Detector gives too few points in a test image
\n
"
);
if
(
keypoints1
.
size
()
>
keypoints0
.
size
())
{
if
(
keypoints1
.
size
()
>
keypoints0
.
size
())
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Strange behavior of the detector. "
"It gives more points count in an image of the smaller size.
\n
"
"original size (%d, %d), keypoints count = %d
\n
"
"reduced size (%d, %d), keypoints count = %d
\n
"
,
image0
.
cols
,
image0
.
rows
,
keypoints0
.
size
(),
image1
.
cols
,
image1
.
rows
,
keypoints1
.
size
());
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_INVALID_OUTPUT
);
"It gives more points count in an image of the smaller size.
\n
"
"original size (%d, %d), keypoints count = %d
\n
"
"reduced size (%d, %d), keypoints count = %d
\n
"
,
image0
.
cols
,
image0
.
rows
,
keypoints0
.
size
(),
image1
.
cols
,
image1
.
rows
,
keypoints1
.
size
());
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_INVALID_OUTPUT
);
return
;
}
scaleKeyPoints
(
keypoints1
,
osiKeypoints1
,
scale
);
scaleKeyPoints
(
keypoints1
,
osiKeypoints1
,
scale
);
vector
<
DMatch
>
matches
;
// image1 is query image (it's reduced image0)
// image0 is train image
matchKeyPoints
(
osiKeypoints1
,
Mat
(),
keypoints0
,
matches
);
vector
<
DMatch
>
matches
;
// image1 is query image (it's reduced image0)
// image0 is train image
matchKeyPoints
(
osiKeypoints1
,
Mat
(),
keypoints0
,
matches
);
const
float
minIntersectRatio
=
0.5
f
;
int
keyPointMatchesCount
=
0
;
int
scaleInliersCount
=
0
;
const
float
minIntersectRatio
=
0.5
f
;
int
keyPointMatchesCount
=
0
;
int
scaleInliersCount
=
0
;
for
(
size_t
m
=
0
;
m
<
matches
.
size
();
m
++
)
for
(
size_t
m
=
0
;
m
<
matches
.
size
();
m
++
)
{
if
(
matches
[
m
].
distance
<
minIntersectRatio
)
continue
;
if
(
matches
[
m
].
distance
<
minIntersectRatio
)
continue
;
keyPointMatchesCount
++
;
keyPointMatchesCount
++
;
// Check does this inlier have consistent sizes
// Check does this inlier have consistent sizes
const
float
maxSizeDiff
=
0.8
;
//0.9f; // grad
float
size0
=
keypoints0
[
matches
[
m
].
trainIdx
].
size
;
float
size0
=
keypoints0
[
matches
[
m
].
trainIdx
].
size
;
float
size1
=
osiKeypoints1
[
matches
[
m
].
queryIdx
].
size
;
CV_Assert
(
size0
>
0
&&
size1
>
0
);
if
(
std
::
min
(
size0
,
size1
)
>
maxSizeDiff
*
std
::
max
(
size0
,
size1
))
CV_Assert
(
size0
>
0
&&
size1
>
0
);
if
(
std
::
min
(
size0
,
size1
)
>
maxSizeDiff
*
std
::
max
(
size0
,
size1
))
scaleInliersCount
++
;
}
float
keyPointMatchesRatio
=
static_cast
<
float
>
(
keyPointMatchesCount
)
/
keypoints1
.
size
();
float
keyPointMatchesRatio
=
static_cast
<
float
>
(
keyPointMatchesCount
)
/
keypoints1
.
size
();
if
(
keyPointMatchesRatio
<
minKeyPointMatchesRatio
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Incorrect keyPointMatchesRatio: curr = %f, min = %f.
\n
"
,
...
...
@@ -477,9 +474,9 @@ protected:
return
;
}
if
(
keyPointMatchesCount
)
if
(
keyPointMatchesCount
)
{
float
scaleInliersRatio
=
static_cast
<
float
>
(
scaleInliersCount
)
/
keyPointMatchesCount
;
float
scaleInliersRatio
=
static_cast
<
float
>
(
scaleInliersCount
)
/
keyPointMatchesCount
;
if
(
scaleInliersRatio
<
minScaleInliersRatio
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Incorrect scaleInliersRatio: curr = %f, min = %f.
\n
"
,
...
...
@@ -490,7 +487,7 @@ protected:
}
#if SHOW_DEBUG_LOG
std
::
cout
<<
"keyPointMatchesRatio - "
<<
keyPointMatchesRatio
<<
" - scaleInliersRatio "
<<
static_cast
<
float
>
(
scaleInliersCount
)
/
keyPointMatchesCount
<<
std
::
endl
;
<<
" - scaleInliersRatio "
<<
static_cast
<
float
>
(
scaleInliersCount
)
/
keyPointMatchesCount
<<
std
::
endl
;
#endif
}
ts
->
set_failed_test_info
(
cvtest
::
TS
::
OK
);
...
...
@@ -505,25 +502,23 @@ class DescriptorScaleInvarianceTest : public cvtest::BaseTest
{
public
:
DescriptorScaleInvarianceTest
(
const
Ptr
<
FeatureDetector
>&
_featureDetector
,
const
Ptr
<
DescriptorExtractor
>&
_descriptorExtractor
,
int
_normType
,
float
_minKeyPointMatchesRatio
,
const
Ptr
<
DescriptorExtractor
>&
_descriptorExtractor
,
int
_normType
,
float
_minDescInliersRatio
)
:
featureDetector
(
_featureDetector
),
descriptorExtractor
(
_descriptorExtractor
),
normType
(
_normType
),
minKeyPointMatchesRatio
(
_minKeyPointMatchesRatio
),
minDescInliersRatio
(
_minDescInliersRatio
)
featureDetector
(
_featureDetector
),
descriptorExtractor
(
_descriptorExtractor
),
normType
(
_normType
),
minDescInliersRatio
(
_minDescInliersRatio
)
{
CV_Assert
(
!
featureDetector
.
empty
());
CV_Assert
(
!
descriptorExtractor
.
empty
());
CV_Assert
(
!
descriptorExtractor
.
empty
());
}
protected
:
void
run
(
int
)
{
const
string
imageFilename
=
string
(
ts
->
get_data_path
())
+
IMAGE_BIKES
;
const
string
imageFilename
=
string
(
ts
->
get_data_path
())
+
IMAGE_BIKES
;
// Read test data
Mat
image0
=
imread
(
imageFilename
);
...
...
@@ -536,102 +531,71 @@ protected:
vector
<
KeyPoint
>
keypoints0
;
featureDetector
->
detect
(
image0
,
keypoints0
);
if
(
keypoints0
.
size
()
<
15
)
CV_Error
(
CV_StsAssert
,
"Detector gives too few points in a test image
\n
"
);
Mat
descriptors0
;
descriptorExtractor
->
compute
(
image0
,
keypoints0
,
descriptors0
);
if
(
keypoints0
.
size
()
<
15
)
CV_Error
(
CV_StsAssert
,
"Detector gives too few points in a test image
\n
"
);
Mat
descriptors0
;
descriptorExtractor
->
compute
(
image0
,
keypoints0
,
descriptors0
);
BFMatcher
bfmatcher
(
normType
);
for
(
int
scale
=
2
;
scale
<=
4
;
scale
++
)
BFMatcher
bfmatcher
(
normType
);
for
(
float
scaleIdx
=
1
;
scaleIdx
<=
3
;
scaleIdx
++
)
{
Mat
image1
;
resize
(
image0
,
image1
,
Size
(),
1.
/
scale
,
1.
/
scale
);
float
scale
=
1.
f
+
scaleIdx
*
0.5
f
;
vector
<
KeyPoint
>
keypoints1
,
osiKeypoints1
;
// osi - original size image
featureDetector
->
detect
(
image1
,
keypoints1
);
if
(
keypoints1
.
size
()
<
15
)
CV_Error
(
CV_StsAssert
,
"Detector gives too few points in a test image
\n
"
);
if
(
keypoints1
.
size
()
>
keypoints0
.
size
()
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Strange behavior of the detector. "
"It gives more points count in an image of the smaller size.
\n
"
"original size (%d, %d), keypoints count = %d
\n
"
"reduced size (%d, %d), keypoints count = %d
\n
"
,
image0
.
cols
,
image0
.
rows
,
keypoints0
.
size
(),
image1
.
cols
,
image1
.
rows
,
keypoints1
.
size
());
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_INVALID_OUTPUT
);
return
;
}
Mat
image1
;
resize
(
image0
,
image1
,
Size
(),
1.
/
scale
,
1.
/
scale
);
Mat
descriptors1
;
descriptorExtractor
->
compute
(
image1
,
keypoints1
,
descriptors1
);
vector
<
DMatch
>
keyPointMatches
,
descMatches
;
// image1 is query image (it's reduced image0)
// image0 is train image
bfmatcher
.
match
(
descriptors1
,
descriptors0
,
descMatches
);
scaleKeyPoints
(
keypoints1
,
osiKeypoints1
,
scale
);
matchKeyPoints
(
osiKeypoints1
,
Mat
(),
keypoints0
,
keyPointMatches
);
const
float
minIntersectRatio
=
0.5
f
;
int
keyPointMatchesCount
=
0
;
for
(
size_t
m
=
0
;
m
<
keyPointMatches
.
size
();
m
++
)
{
if
(
keyPointMatches
[
m
].
distance
>=
minIntersectRatio
)
keyPointMatchesCount
++
;
}
int
descInliersCount
=
0
;
for
(
size_t
m
=
0
;
m
<
descMatches
.
size
();
m
++
)
{
int
queryIdx
=
descMatches
[
m
].
queryIdx
;
if
(
keyPointMatches
[
queryIdx
].
distance
>=
minIntersectRatio
&&
descMatches
[
m
].
trainIdx
==
keyPointMatches
[
queryIdx
].
trainIdx
)
descInliersCount
++
;
}
vector
<
KeyPoint
>
keypoints1
;
scaleKeyPoints
(
keypoints0
,
keypoints1
,
1.
/
scale
);
Mat
descriptors1
;
descriptorExtractor
->
compute
(
image1
,
keypoints1
,
descriptors1
);
float
keyPointMatchesRatio
=
static_cast
<
float
>
(
keyPointMatchesCount
)
/
keypoints1
.
size
();
if
(
keyPointMatchesRatio
<
minKeyPointMatchesRatio
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Incorrect keyPointMatchesRatio: curr = %f, min = %f.
\n
"
,
keyPointMatchesRatio
,
minKeyPointMatchesRatio
);
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_BAD_ACCURACY
);
return
;
}
vector
<
DMatch
>
descMatches
;
bfmatcher
.
match
(
descriptors0
,
descriptors1
,
descMatches
);
if
(
keyPointMatchesCount
)
const
float
minIntersectRatio
=
0.5
f
;
int
descInliersCount
=
0
;
for
(
size_t
m
=
0
;
m
<
descMatches
.
size
();
m
++
)
{
float
descInliersRatio
=
static_cast
<
float
>
(
descInliersCount
)
/
keyPointMatchesCount
;
if
(
descInliersRatio
<
minDescInliersRatio
)
const
KeyPoint
&
transformed_p0
=
keypoints0
[
descMatches
[
m
].
queryIdx
];
const
KeyPoint
&
p1
=
keypoints0
[
descMatches
[
m
].
trainIdx
];
if
(
calcIntersectRatio
(
transformed_p0
.
pt
,
0.5
f
*
transformed_p0
.
size
,
p1
.
pt
,
0.5
f
*
p1
.
size
)
>=
minIntersectRatio
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Incorrect descInliersRatio: curr = %f, min = %f.
\n
"
,
descInliersRatio
,
minDescInliersRatio
);
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_BAD_ACCURACY
);
return
;
descInliersCount
++
;
}
}
float
descInliersRatio
=
static_cast
<
float
>
(
descInliersCount
)
/
keypoints0
.
size
();
if
(
descInliersRatio
<
minDescInliersRatio
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Incorrect descInliersRatio: curr = %f, min = %f.
\n
"
,
descInliersRatio
,
minDescInliersRatio
);
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_BAD_ACCURACY
);
return
;
}
#if SHOW_DEBUG_LOG
std
::
cout
<<
"keyPointMatchesRatio - "
<<
keyPointMatchesRatio
<<
" - descInliersRatio "
<<
static_cast
<
float
>
(
descInliersCount
)
/
keyPointMatchesCount
<<
std
::
endl
;
std
::
cout
<<
"descInliersRatio "
<<
static_cast
<
float
>
(
descInliersCount
)
/
keypoints0
.
size
()
<<
std
::
endl
;
#endif
}
ts
->
set_failed_test_info
(
cvtest
::
TS
::
OK
);
}
Ptr
<
FeatureDetector
>
featureDetector
;
Ptr
<
DescriptorExtractor
>
descriptorExtractor
;
int
normType
;
Ptr
<
DescriptorExtractor
>
descriptorExtractor
;
int
normType
;
float
minKeyPointMatchesRatio
;
float
minDescInliersRatio
;
};
// Tests registration
// Detector's rotation invariance check
/*
* Detector's rotation invariance check
*/
TEST
(
Features2d_RotationInvariance_Detector_SURF
,
regression
)
{
DetectorRotationInvarianceTest
test
(
Algorithm
::
create
<
FeatureDetector
>
(
"Feature2D.SURF"
),
0.44
f
,
0.45
f
,
0.76
f
);
test
.
safe_run
();
}
...
...
@@ -639,19 +603,20 @@ TEST(Features2d_RotationInvariance_Detector_SURF, regression)
TEST
(
Features2d_RotationInvariance_Detector_SIFT
,
regression
)
{
DetectorRotationInvarianceTest
test
(
Algorithm
::
create
<
FeatureDetector
>
(
"Feature2D.SIFT"
),
0.64
f
,
0.74
f
);
0.75
f
,
0.76
f
);
test
.
safe_run
();
}
// Descriptors's rotation invariance check
/*
* Descriptors's rotation invariance check
*/
TEST
(
Features2d_RotationInvariance_Descriptor_SURF
,
regression
)
{
DescriptorRotationInvarianceTest
test
(
Algorithm
::
create
<
FeatureDetector
>
(
"Feature2D.SURF"
),
Algorithm
::
create
<
DescriptorExtractor
>
(
"Feature2D.SURF"
),
NORM_L1
,
0.44
f
,
0.63
f
);
0.83
f
);
test
.
safe_run
();
}
...
...
@@ -660,45 +625,46 @@ TEST(Features2d_RotationInvariance_Descriptor_SIFT, regression)
DescriptorRotationInvarianceTest
test
(
Algorithm
::
create
<
FeatureDetector
>
(
"Feature2D.SIFT"
),
Algorithm
::
create
<
DescriptorExtractor
>
(
"Feature2D.SIFT"
),
NORM_L1
,
0.64
f
,
0.72
f
);
0.98
f
);
test
.
safe_run
();
}
// Detector's scale invariance check
/*
* Detector's scale invariance check
*/
TEST
(
Features2d_ScaleInvariance_Detector_SURF
,
regression
)
{
DetectorScaleInvarianceTest
test
(
Algorithm
::
create
<
FeatureDetector
>
(
"Feature2D.SURF"
),
0.62
f
,
0.68
f
);
0.64
f
,
0.84
f
);
test
.
safe_run
();
}
TEST
(
Features2d_ScaleInvariance_Detector_SIFT
,
regression
)
{
DetectorScaleInvarianceTest
test
(
Algorithm
::
create
<
FeatureDetector
>
(
"Feature2D.SIFT"
),
0.59
f
,
0.94
f
);
0.69
f
,
0.99
f
);
test
.
safe_run
();
}
// Descriptor's scale invariance check
/*
* Descriptor's scale invariance check
*/
TEST
(
Features2d_ScaleInvariance_Descriptor_SURF
,
regression
)
{
DescriptorScaleInvarianceTest
test
(
Algorithm
::
create
<
FeatureDetector
>
(
"Feature2D.SURF"
),
Algorithm
::
create
<
DescriptorExtractor
>
(
"Feature2D.SURF"
),
NORM_L1
,
0.62
f
,
0.68
f
);
0.61
f
);
test
.
safe_run
();
}
TEST
(
Features2d_ScaleInvariance_Descriptor_SIFT
,
regression
)
{
DescriptorScaleInvarianceTest
test
(
Algorithm
::
create
<
FeatureDetector
>
(
"Feature2D.SIFT"
),
Algorithm
::
create
<
DescriptorExtractor
>
(
"Feature2D.SIFT"
),
NORM_L1
,
0.59
f
,
0.78
f
);
test
.
safe_run
();
}
\ No newline at end of file
//TEST(Features2d_ScaleInvariance_Descriptor_SIFT, regression)
//{
// DescriptorScaleInvarianceTest test(Algorithm::create<FeatureDetector>("Feature2D.SIFT"),
// Algorithm::create<DescriptorExtractor>("Feature2D.SIFT"),
// NORM_L1,
// 0.14f);
// test.safe_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