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
276f3b88
Commit
276f3b88
authored
Jun 16, 2010
by
Ilya Lysenkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added distance threshold-based matching
parent
f4dba468
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
154 additions
and
20 deletions
+154
-20
features2d.hpp
modules/features2d/include/opencv2/features2d/features2d.hpp
+102
-5
descriptors.cpp
modules/features2d/src/descriptors.cpp
+41
-11
adetectordescriptor_evaluation.cpp
tests/cv/src/adetectordescriptor_evaluation.cpp
+11
-4
No files found.
modules/features2d/include/opencv2/features2d/features2d.hpp
View file @
276f3b88
...
...
@@ -1573,9 +1573,9 @@ public:
* Find the best match for each descriptor from a query set
*
* query The query set of descriptors
* match
ings Matching
s of the closest matches from the training set
* match
es DMatche
s of the closest matches from the training set
*/
void
match
(
const
Mat
&
query
,
vector
<
DMatch
>&
match
ing
s
)
const
;
void
match
(
const
Mat
&
query
,
vector
<
DMatch
>&
match
e
s
)
const
;
/*
* Find the best matches between two descriptor sets, with constraints
...
...
@@ -1586,10 +1586,36 @@ public:
*
* query The query set of descriptors
* mask Mask specifying permissible matches.
* match
ings Matching
s of the closest matches from the training set
* match
es DMatche
s of the closest matches from the training set
*/
void
match
(
const
Mat
&
query
,
const
Mat
&
mask
,
vector
<
DMatch
>&
matchings
)
const
;
vector
<
DMatch
>&
matches
)
const
;
/*
* Find many matches for each descriptor from a query set
*
* query The query set of descriptors
* matches DMatches of the closest matches from the training set
* threshold Distance threshold for descriptors matching
*/
void
match
(
const
Mat
&
query
,
vector
<
vector
<
DMatch
>
>&
matches
,
float
threshold
)
const
;
/*
* Find many matches for each descriptor from a query set, with constraints
* on which pairs of descriptors can be matched.
*
* The mask describes which descriptors can be matched. descriptors_1[i]
* can be matched with descriptors_2[j] only if mask.at<char>(i,j) is non-zero.
*
* query The query set of descriptors
* mask Mask specifying permissible matches.
* matches DMatches of the closest matches from the training set
* threshold Distance threshold for descriptors matching
*/
void
match
(
const
Mat
&
query
,
const
Mat
&
mask
,
vector
<
vector
<
DMatch
>
>&
matches
,
float
threshold
)
const
;
/*
* Find the best keypoint matches for small view changes.
...
...
@@ -1627,6 +1653,10 @@ protected:
virtual
void
matchImpl
(
const
Mat
&
descriptors_1
,
const
Mat
&
descriptors_2
,
const
Mat
&
mask
,
vector
<
DMatch
>&
matches
)
const
=
0
;
virtual
void
matchImpl
(
const
Mat
&
descriptors_1
,
const
Mat
&
descriptors_2
,
const
Mat
&
mask
,
vector
<
vector
<
DMatch
>
>&
matches
,
float
threshold
)
const
=
0
;
static
bool
possibleMatch
(
const
Mat
&
mask
,
int
index_1
,
int
index_2
)
{
return
mask
.
empty
()
||
mask
.
at
<
char
>
(
index_1
,
index_2
);
...
...
@@ -1674,6 +1704,18 @@ inline void DescriptorMatcher::match( const Mat& query, const Mat& mask,
matchImpl
(
query
,
train
,
mask
,
matches
);
}
inline
void
DescriptorMatcher
::
match
(
const
Mat
&
query
,
vector
<
vector
<
DMatch
>
>&
matches
,
float
threshold
)
const
{
matchImpl
(
query
,
train
,
Mat
(),
matches
,
threshold
);
}
inline
void
DescriptorMatcher
::
match
(
const
Mat
&
query
,
const
Mat
&
mask
,
vector
<
vector
<
DMatch
>
>&
matches
,
float
threshold
)
const
{
matchImpl
(
query
,
train
,
mask
,
matches
,
threshold
);
}
inline
void
DescriptorMatcher
::
clear
()
{
train
.
release
();
...
...
@@ -1701,6 +1743,9 @@ protected:
virtual
void
matchImpl
(
const
Mat
&
descriptors_1
,
const
Mat
&
descriptors_2
,
const
Mat
&
mask
,
vector
<
DMatch
>&
matches
)
const
;
virtual
void
matchImpl
(
const
Mat
&
descriptors_1
,
const
Mat
&
descriptors_2
,
const
Mat
&
mask
,
vector
<
vector
<
DMatch
>
>&
matches
,
float
threshold
)
const
;
Distance
distance
;
};
...
...
@@ -1764,6 +1809,46 @@ void BruteForceMatcher<Distance>::matchImpl( const Mat& descriptors_1, const Mat
}
}
template
<
class
Distance
>
void
BruteForceMatcher
<
Distance
>::
matchImpl
(
const
Mat
&
descriptors_1
,
const
Mat
&
descriptors_2
,
const
Mat
&
mask
,
vector
<
vector
<
DMatch
>
>&
matches
,
float
threshold
)
const
{
typedef
typename
Distance
::
ValueType
ValueType
;
typedef
typename
Distance
::
ResultType
DistanceType
;
assert
(
mask
.
empty
()
||
(
mask
.
rows
==
descriptors_1
.
rows
&&
mask
.
cols
==
descriptors_2
.
rows
)
);
assert
(
descriptors_1
.
cols
==
descriptors_2
.
cols
||
descriptors_1
.
empty
()
||
descriptors_2
.
empty
()
);
assert
(
DataType
<
ValueType
>::
type
==
descriptors_1
.
type
()
||
descriptors_1
.
empty
()
);
assert
(
DataType
<
ValueType
>::
type
==
descriptors_2
.
type
()
||
descriptors_2
.
empty
()
);
int
dimension
=
descriptors_1
.
cols
;
matches
.
resize
(
descriptors_1
.
rows
);
for
(
int
i
=
0
;
i
<
descriptors_1
.
rows
;
i
++
)
{
const
ValueType
*
d1
=
descriptors_1
.
ptr
<
ValueType
>
(
i
);
for
(
int
j
=
0
;
j
<
descriptors_2
.
rows
;
j
++
)
{
if
(
possibleMatch
(
mask
,
i
,
j
)
)
{
const
ValueType
*
d2
=
descriptors_2
.
ptr
<
ValueType
>
(
j
);
DistanceType
curDistance
=
distance
(
d1
,
d2
,
dimension
);
if
(
curDistance
<
threshold
)
{
DMatch
match
;
match
.
distance
=
curDistance
;
match
.
indexQuery
=
i
;
match
.
indexTrain
=
j
;
matches
[
i
].
push_back
(
match
);
}
}
}
}
}
DescriptorMatcher
*
createDescriptorMatcher
(
const
string
&
descriptorMatcherType
);
/****************************************************************************************\
...
...
@@ -1835,6 +1920,8 @@ public:
// matches A vector to be filled with keypoint matches
virtual
void
match
(
const
Mat
&
image
,
vector
<
KeyPoint
>&
points
,
vector
<
DMatch
>&
matches
)
{};
virtual
void
match
(
const
Mat
&
image
,
vector
<
KeyPoint
>&
points
,
vector
<
vector
<
DMatch
>
>&
matches
,
float
threshold
)
{};
// Clears keypoints storing in collection
virtual
void
clear
();
...
...
@@ -2039,7 +2126,9 @@ public:
virtual
void
match
(
const
Mat
&
image
,
vector
<
KeyPoint
>&
keypoints
,
vector
<
int
>&
indices
);
virtual
void
match
(
const
Mat
&
image
,
vector
<
KeyPoint
>&
points
,
vector
<
DMatch
>&
matches
);
virtual
void
match
(
const
Mat
&
image
,
vector
<
KeyPoint
>&
points
,
vector
<
DMatch
>&
matches
);
virtual
void
match
(
const
Mat
&
image
,
vector
<
KeyPoint
>&
points
,
vector
<
vector
<
DMatch
>
>&
matches
,
float
threshold
);
virtual
void
classify
(
const
Mat
&
image
,
vector
<
KeyPoint
>&
keypoints
);
...
...
@@ -2105,6 +2194,14 @@ public:
matcher
.
match
(
descriptors
,
matches
);
}
virtual
void
match
(
const
Mat
&
image
,
vector
<
KeyPoint
>&
points
,
vector
<
vector
<
DMatch
>
>&
matches
,
float
threshold
)
{
Mat
descriptors
;
extractor
.
compute
(
image
,
points
,
descriptors
);
matcher
.
match
(
descriptors
,
matches
,
threshold
);
}
virtual
void
clear
()
{
GenericDescriptorMatch
::
clear
();
...
...
modules/features2d/src/descriptors.cpp
View file @
276f3b88
...
...
@@ -41,6 +41,8 @@
#include "precomp.hpp"
//#define _KDTREE
using
namespace
std
;
namespace
cv
{
...
...
@@ -439,21 +441,22 @@ void OneWayDescriptorMatch::match( const Mat& image, vector<KeyPoint>& points, v
match
(
image
,
points
,
matchings
);
for
(
size_t
i
=
0
;
i
<
points
.
size
();
i
++
)
indices
[
i
]
=
matchings
[
i
].
index
;
indices
[
i
]
=
matchings
[
i
].
index
Train
;
}
void
OneWayDescriptorMatch
::
match
(
const
Mat
&
image
,
vector
<
KeyPoint
>&
points
,
vector
<
DMatch
>&
match
ing
s
)
void
OneWayDescriptorMatch
::
match
(
const
Mat
&
image
,
vector
<
KeyPoint
>&
points
,
vector
<
DMatch
>&
match
e
s
)
{
match
ing
s
.
resize
(
points
.
size
()
);
match
e
s
.
resize
(
points
.
size
()
);
IplImage
_image
=
image
;
for
(
size_t
i
=
0
;
i
<
points
.
size
();
i
++
)
{
int
poseIdx
=
-
1
;
DMatch
matching
;
matching
.
index
=
-
1
;
base
->
FindDescriptor
(
&
_image
,
points
[
i
].
pt
,
matching
.
index
,
poseIdx
,
matching
.
distance
);
matchings
[
i
]
=
matching
;
DMatch
match
;
match
.
indexQuery
=
i
;
match
.
indexTrain
=
-
1
;
base
->
FindDescriptor
(
&
_image
,
points
[
i
].
pt
,
match
.
indexTrain
,
poseIdx
,
match
.
distance
);
matches
[
i
]
=
match
;
}
}
...
...
@@ -744,18 +747,45 @@ void FernDescriptorMatch::match( const Mat& image, vector<KeyPoint>& keypoints,
}
}
void
FernDescriptorMatch
::
match
(
const
Mat
&
image
,
vector
<
KeyPoint
>&
keypoints
,
vector
<
DMatch
>&
match
ing
s
)
void
FernDescriptorMatch
::
match
(
const
Mat
&
image
,
vector
<
KeyPoint
>&
keypoints
,
vector
<
DMatch
>&
match
e
s
)
{
trainFernClassifier
();
match
ing
s
.
resize
(
keypoints
.
size
()
);
match
e
s
.
resize
(
keypoints
.
size
()
);
vector
<
float
>
signature
(
(
size_t
)
classifier
->
getClassCount
()
);
for
(
size_t
pi
=
0
;
pi
<
keypoints
.
size
();
pi
++
)
{
calcBestProbAndMatchIdx
(
image
,
keypoints
[
pi
].
pt
,
matchings
[
pi
].
distance
,
matchings
[
pi
].
index
,
signature
);
matches
[
pi
].
indexQuery
=
pi
;
calcBestProbAndMatchIdx
(
image
,
keypoints
[
pi
].
pt
,
matches
[
pi
].
distance
,
matches
[
pi
].
indexTrain
,
signature
);
//matching[pi].distance is log of probability so we need to transform it
matchings
[
pi
].
distance
=
-
matchings
[
pi
].
distance
;
matches
[
pi
].
distance
=
-
matches
[
pi
].
distance
;
}
}
void
FernDescriptorMatch
::
match
(
const
Mat
&
image
,
vector
<
KeyPoint
>&
keypoints
,
vector
<
vector
<
DMatch
>
>&
matches
,
float
threshold
)
{
trainFernClassifier
();
matches
.
resize
(
keypoints
.
size
()
);
vector
<
float
>
signature
(
(
size_t
)
classifier
->
getClassCount
()
);
for
(
size_t
pi
=
0
;
pi
<
keypoints
.
size
();
pi
++
)
{
(
*
classifier
)(
image
,
keypoints
[
pi
].
pt
,
signature
);
DMatch
match
;
match
.
indexQuery
=
pi
;
for
(
size_t
ci
=
0
;
ci
<
(
size_t
)
classifier
->
getClassCount
();
ci
++
)
{
if
(
-
signature
[
ci
]
<
threshold
)
{
match
.
distance
=
-
signature
[
ci
];
match
.
indexTrain
=
ci
;
matches
[
pi
].
push_back
(
match
);
}
}
}
}
...
...
tests/cv/src/adetectordescriptor_evaluation.cpp
View file @
276f3b88
...
...
@@ -1447,12 +1447,19 @@ void DescriptorQualityTest::runDatasetTest (const vector<Mat> &imgs, const vecto
readKeypoints
(
keypontsFS
,
keypoints2
,
ci
+
1
);
transformToEllipticKeyPoints
(
keypoints2
,
ekeypoints2
);
descMatch
->
add
(
imgs
[
ci
+
1
],
keypoints2
);
vector
<
DMatch
>
matches1to2
;
descMatch
->
match
(
imgs
[
0
],
keypoints1
,
matches1to2
);
vector
<
DMatchForEvaluation
>
matches
(
matches1to2
.
size
()
)
;
vector
<
vector
<
DMatch
>
>
matches1to2
;
descMatch
->
match
(
imgs
[
0
],
keypoints1
,
matches1to2
,
std
::
numeric_limits
<
float
>::
max
()
);
vector
<
DMatchForEvaluation
>
matches
;
for
(
size_t
i
=
0
;
i
<
matches1to2
.
size
();
i
++
)
{
matches
[
i
].
match
=
matches1to2
[
i
];
//TODO: use copy
for
(
size_t
j
=
0
;
j
<
matches1to2
[
i
].
size
();
j
++
)
{
DMatchForEvaluation
match
;
match
.
match
=
matches1to2
[
i
][
j
];
matches
.
push_back
(
match
);
//std::copy( matches1to2[i].begin(), matches1to2[i].end(), std::back_inserter( matches ) );
}
}
// TODO if( commRunParams[di].matchFilter )
...
...
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