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
c6e43c38
Commit
c6e43c38
authored
Nov 23, 2010
by
Maria Dimashova
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
updated documentation on features2d; minor features2d changes
parent
562a3bd5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
435 additions
and
361 deletions
+435
-361
features2d_common_detection_description.tex
doc/features2d_common_detection_description.tex
+355
-276
features2d.hpp
modules/features2d/include/opencv2/features2d/features2d.hpp
+13
-12
descriptors.cpp
modules/features2d/src/descriptors.cpp
+1
-0
matchers.cpp
modules/features2d/src/matchers.cpp
+65
-72
matching_to_many_images.cpp
samples/cpp/matching_to_many_images.cpp
+1
-1
No files found.
doc/features2d_common_detection_description.tex
View file @
c6e43c38
...
@@ -64,17 +64,17 @@ Abstract base class for 2D image feature detectors.
...
@@ -64,17 +64,17 @@ Abstract base class for 2D image feature detectors.
class CV
_
EXPORTS FeatureDetector
class CV
_
EXPORTS FeatureDetector
{
{
public:
public:
virtual ~FeatureDetector()
{}
virtual ~FeatureDetector()
;
v
irtual v
oid detect( const Mat
&
image, vector<KeyPoint>
&
keypoints,
void detect( const Mat
&
image, vector<KeyPoint>
&
keypoints,
const Mat
&
mask=Mat() ) const = 0
;
const Mat
&
mask=Mat() ) const
;
void detect( const vector<Mat>
&
image
Collection
,
void detect( const vector<Mat>
&
image
s
,
vector<vector<KeyPoint> >
&
pointCollection
,
vector<vector<KeyPoint> >
&
keypoints
,
const vector<Mat>
&
masks=vector<Mat>() ) const;
const vector<Mat>
&
masks=vector<Mat>() ) const;
virtual void read(const FileNode
&
)
{}
virtual void read(const FileNode
&
)
;
virtual void write(FileStorage
&
) const
{}
virtual void write(FileStorage
&
) const
;
protected:
protected:
...
...
...
@@ -86,11 +86,8 @@ Detect keypoints in an image (first variant) or image set (second variant).
...
@@ -86,11 +86,8 @@ Detect keypoints in an image (first variant) or image set (second variant).
\cvdefCpp
{
\cvdefCpp
{
void FeatureDetector::detect( const Mat
\&
image,
void FeatureDetector::detect( const Mat
\&
image,
\par
vector<KeyPoint>
\&
keypoints,
\par
vector<KeyPoint>
\&
keypoints,
\par
const Mat
\&
mask=Mat() ) const;
\\
\par
const Mat
\&
mask=Mat() ) const;
void FeatureDetector::detect( const vector<Mat>
\&
imageCollection,
\par
vector<vector<KeyPoint> >
\&
pointCollection,
\par
const vector<Mat>
\&
masks=vector<Mat>() ) const;
}
}
\begin{description}
\begin{description}
...
@@ -98,17 +95,23 @@ void FeatureDetector::detect( const vector<Mat>\& imageCollection,
...
@@ -98,17 +95,23 @@ void FeatureDetector::detect( const vector<Mat>\& imageCollection,
\cvarg
{
keypoints
}{
The detected keypoints.
}
\cvarg
{
keypoints
}{
The detected keypoints.
}
\cvarg
{
mask
}{
Mask specifying where to look for keypoints (optional). Must be a char matrix
\cvarg
{
mask
}{
Mask specifying where to look for keypoints (optional). Must be a char matrix
with non-zero values in the region of interest.
}
with non-zero values in the region of interest.
}
\end{description}
\end{description}
\cvdefCpp
{
void FeatureDetector::detect( const vector<Mat>
\&
images,
\par
vector<vector<KeyPoint> >
\&
keypoints,
\par
const vector<Mat>
\&
masks=vector<Mat>() ) const;
}
\begin{description}
\begin{description}
\cvarg
{
image
Collection
}{
Image collection
.
}
\cvarg
{
image
s
}{
Images set
.
}
\cvarg
{
pointCollection
}{
Collection of keypoints detected in an input images
.
}
\cvarg
{
keypoints
}{
Collection of keypoints detected in an input images. keypoints[i] is a set of keypoints detected in an images[i]
.
}
\cvarg
{
masks
}{
Masks for each input image specifying where to look for keypoints (optional).
\cvarg
{
masks
}{
Masks for each input image specifying where to look for keypoints (optional).
masks[i] is a mask for images[i].
Each element of
\texttt
{
masks
}
vector must be a char matrix with non-zero values in the region of interest.
}
Each element of
\texttt
{
masks
}
vector must be a char matrix with non-zero values in the region of interest.
}
\end{description}
\end{description}
\cvCppFunc
{
FeatureDetector::read
}
\cvCppFunc
{
FeatureDetector::read
}
Read feature detector from file node.
Read feature detector
object
from file node.
\cvdefCpp
{
\cvdefCpp
{
void FeatureDetector::read( const FileNode
\&
fn );
void FeatureDetector::read( const FileNode
\&
fn );
...
@@ -119,7 +122,7 @@ void FeatureDetector::read( const FileNode\& fn );
...
@@ -119,7 +122,7 @@ void FeatureDetector::read( const FileNode\& fn );
\end{description}
\end{description}
\cvCppFunc
{
FeatureDetector::write
}
\cvCppFunc
{
FeatureDetector::write
}
Write feature detector to file storage.
Write feature detector
object
to file storage.
\cvdefCpp
{
\cvdefCpp
{
void FeatureDetector::write( FileStorage
\&
fs ) const;
void FeatureDetector::write( FileStorage
\&
fs ) const;
...
@@ -136,34 +139,45 @@ Wrapping class for feature detection using \cvCppCross{FAST} method.
...
@@ -136,34 +139,45 @@ Wrapping class for feature detection using \cvCppCross{FAST} method.
class FastFeatureDetector : public FeatureDetector
class FastFeatureDetector : public FeatureDetector
{
{
public:
public:
FastFeatureDetector( int
_
threshold=1, bool
_
nonmaxSuppression=true );
FastFeatureDetector( int threshold=1, bool nonmaxSuppression=true );
virtual void detect( const Mat
&
image, vector<KeyPoint>
&
keypoints,
const Mat
&
mask=Mat() ) const;
virtual void read( const FileNode
&
fn );
virtual void read( const FileNode
&
fn );
virtual void write( FileStorage
&
fs ) const;
virtual void write( FileStorage
&
fs ) const;
protected:
protected:
...
...
}
;
}
;
\end{lstlisting}
\end{lstlisting}
\cvclass
{
GoodFeaturesToTrackDetector
}
\cvclass
{
GoodFeaturesToTrackDetector
}
Wrapping class for feature detection using
\cvCppCross
{
goodFeaturesToTrack
}
method
.
Wrapping class for feature detection using
\cvCppCross
{
goodFeaturesToTrack
}
function
.
\begin{lstlisting}
\begin{lstlisting}
class GoodFeaturesToTrackDetector : public FeatureDetector
class GoodFeaturesToTrackDetector : public FeatureDetector
{
{
public:
public:
GoodFeaturesToTrackDetector( int
_
maxCorners, double
_
qualityLevel,
class Params
double
_
minDistance, int
_
blockSize=3,
{
bool
_
useHarrisDetector=false, double
_
k=0.04 );
public:
virtual void detect( const Mat
&
image, vector<KeyPoint>
&
keypoints,
Params( int maxCorners=1000, double qualityLevel=0.01,
const Mat
&
mask=Mat() ) const;
double minDistance=1., int blockSize=3,
bool useHarrisDetector=false, double k=0.04 );
void read( const FileNode
&
fn );
void write( FileStorage
&
fs ) const;
int maxCorners;
double qualityLevel;
double minDistance;
int blockSize;
bool useHarrisDetector;
double k;
}
;
GoodFeaturesToTrackDetector( const GoodFeaturesToTrackDetector::Params
&
params=
GoodFeaturesToTrackDetector::Params() );
GoodFeaturesToTrackDetector( int maxCorners, double qualityLevel,
double minDistance, int blockSize=3,
bool useHarrisDetector=false, double k=0.04 );
virtual void read( const FileNode
&
fn );
virtual void read( const FileNode
&
fn );
virtual void write( FileStorage
&
fs ) const;
virtual void write( FileStorage
&
fs ) const;
protected:
protected:
...
...
}
;
}
;
...
@@ -176,17 +190,13 @@ Wrapping class for feature detection using \cvCppCross{MSER} class.
...
@@ -176,17 +190,13 @@ Wrapping class for feature detection using \cvCppCross{MSER} class.
class MserFeatureDetector : public FeatureDetector
class MserFeatureDetector : public FeatureDetector
{
{
public:
public:
MserFeatureDetector( CvMSERParams params=cvMSERParams
() );
MserFeatureDetector( CvMSERParams params=cvMSERParams() );
MserFeatureDetector( int delta, int minArea, int maxArea,
MserFeatureDetector( int delta, int minArea, int maxArea,
double maxVariation, double minDiversity,
double maxVariation, double minDiversity,
int maxEvolution, double areaThreshold,
int maxEvolution, double areaThreshold,
double minMargin, int edgeBlurSize );
double minMargin, int edgeBlurSize );
virtual void detect( const Mat
&
image, vector<KeyPoint>
&
keypoints,
const Mat
&
mask=Mat() ) const;
virtual void read( const FileNode
&
fn );
virtual void read( const FileNode
&
fn );
virtual void write( FileStorage
&
fs ) const;
virtual void write( FileStorage
&
fs ) const;
protected:
protected:
...
...
}
;
}
;
...
@@ -202,12 +212,8 @@ public:
...
@@ -202,12 +212,8 @@ public:
StarFeatureDetector( int maxSize=16, int responseThreshold=30,
StarFeatureDetector( int maxSize=16, int responseThreshold=30,
int lineThresholdProjected = 10,
int lineThresholdProjected = 10,
int lineThresholdBinarized=8, int suppressNonmaxSize=5 );
int lineThresholdBinarized=8, int suppressNonmaxSize=5 );
virtual void detect( const Mat
&
image, vector<KeyPoint>
&
keypoints,
const Mat
&
mask=Mat() ) const;
virtual void read( const FileNode
&
fn );
virtual void read( const FileNode
&
fn );
virtual void write( FileStorage
&
fs ) const;
virtual void write( FileStorage
&
fs ) const;
protected:
protected:
...
...
}
;
}
;
...
@@ -220,20 +226,18 @@ Wrapping class for feature detection using \cvCppCross{SIFT} class.
...
@@ -220,20 +226,18 @@ Wrapping class for feature detection using \cvCppCross{SIFT} class.
class SiftFeatureDetector : public FeatureDetector
class SiftFeatureDetector : public FeatureDetector
{
{
public:
public:
SiftFeatureDetector( double threshold=SIFT::DetectorParams::GET
_
DEFAULT
_
THRESHOLD(),
SiftFeatureDetector(
double edgeThreshold=SIFT::DetectorParams::GET
_
DEFAULT
_
EDGE
_
THRESHOLD(),
const SIFT::DetectorParams
&
detectorParams=SIFT::DetectorParams(),
int nOctaves=SIFT::CommonParams::DEFAULT
_
NOCTAVES,
const SIFT::CommonParams
&
commonParams=SIFT::CommonParams() );
int nOctaveLayers=SIFT::CommonParams::DEFAULT
_
NOCTAVE
_
LAYERS,
SiftFeatureDetector( double threshold, double edgeThreshold,
int firstOctave=SIFT::CommonParams::DEFAULT
_
FIRST
_
OCTAVE,
int nOctaves=SIFT::CommonParams::DEFAULT
_
NOCTAVES,
int angleMode=SIFT::CommonParams::FIRST
_
ANGLE );
int nOctaveLayers=SIFT::CommonParams::DEFAULT
_
NOCTAVE
_
LAYERS,
virtual void detect( const Mat
&
image, vector<KeyPoint>
&
keypoints,
int firstOctave=SIFT::CommonParams::DEFAULT
_
FIRST
_
OCTAVE,
const Mat
&
mask=Mat() ) const;
int angleMode=SIFT::CommonParams::FIRST
_
ANGLE );
virtual void read( const FileNode
&
fn );
virtual void read( const FileNode
&
fn );
virtual void write( FileStorage
&
fs ) const;
virtual void write( FileStorage
&
fs ) const;
protected:
protected:
...
...
}
;
}
;
\end{lstlisting}
\end{lstlisting}
...
@@ -246,14 +250,10 @@ class SurfFeatureDetector : public FeatureDetector
...
@@ -246,14 +250,10 @@ class SurfFeatureDetector : public FeatureDetector
public:
public:
SurfFeatureDetector( double hessianThreshold = 400., int octaves = 3,
SurfFeatureDetector( double hessianThreshold = 400., int octaves = 3,
int octaveLayers = 4 );
int octaveLayers = 4 );
virtual void detect( const Mat
&
image, vector<KeyPoint>
&
keypoints,
const Mat
&
mask=Mat() ) const;
virtual void read( const FileNode
&
fn );
virtual void read( const FileNode
&
fn );
virtual void write( FileStorage
&
fs ) const;
virtual void write( FileStorage
&
fs ) const;
protected:
protected:
...
...
}
;
}
;
\end{lstlisting}
\end{lstlisting}
...
@@ -275,13 +275,8 @@ public:
...
@@ -275,13 +275,8 @@ public:
GridAdaptedFeatureDetector( const Ptr<FeatureDetector>
&
detector,
GridAdaptedFeatureDetector( const Ptr<FeatureDetector>
&
detector,
int maxTotalKeypoints, int gridRows=4,
int maxTotalKeypoints, int gridRows=4,
int gridCols=4 );
int gridCols=4 );
virtual void detect( const Mat
&
image, vector<KeyPoint>
&
keypoints,
virtual void read( const FileNode
&
fn );
const Mat
&
mask=Mat() ) const;
virtual void write( FileStorage
&
fs ) const;
// todo read/write
virtual void read( const FileNode
&
fn )
{}
virtual void write( FileStorage
&
fs ) const
{}
protected:
protected:
...
...
}
;
}
;
...
@@ -297,12 +292,8 @@ class PyramidAdaptedFeatureDetector : public FeatureDetector
...
@@ -297,12 +292,8 @@ class PyramidAdaptedFeatureDetector : public FeatureDetector
public:
public:
PyramidAdaptedFeatureDetector( const Ptr<FeatureDetector>
&
detector,
PyramidAdaptedFeatureDetector( const Ptr<FeatureDetector>
&
detector,
int levels=2 );
int levels=2 );
virtual void detect( const Mat
&
image, vector<KeyPoint>
&
keypoints,
virtual void read( const FileNode
&
fn );
const Mat
&
mask=Mat() ) const;
virtual void write( FileStorage
&
fs ) const;
// todo read/write
virtual void read( const FileNode
&
fn )
{}
virtual void write( FileStorage
&
fs ) const
{}
protected:
protected:
...
...
}
;
}
;
...
@@ -358,10 +349,11 @@ Ptr<FeatureDetector> createFeatureDetector( const string& detectorType );
...
@@ -358,10 +349,11 @@ Ptr<FeatureDetector> createFeatureDetector( const string& detectorType );
\end{lstlisting}
\end{lstlisting}
\begin{description}
\begin{description}
\cvarg
{
detectorType
}{
Feature detector type
, e.g. ''SURF'', ''FAST'', ..
.
}
\cvarg
{
detectorType
}{
Feature detector type.
}
\end{description}
\end{description}
Now the following detector types are supported ''FAST'', ''STAR'', ''SIFT'',
''SURF'', ''MSER'', ''GFTT'', ''HARRIS''.
\section
{
Common Interfaces of Descriptor Extractors
}
\section
{
Common Interfaces of Descriptor Extractors
}
Extractors of keypoint descriptors in OpenCV have wrappers with common interface that enables to switch easily
Extractors of keypoint descriptors in OpenCV have wrappers with common interface that enables to switch easily
...
@@ -376,17 +368,15 @@ Abstract base class for computing descriptors for image keypoints.
...
@@ -376,17 +368,15 @@ Abstract base class for computing descriptors for image keypoints.
class CV
_
EXPORTS DescriptorExtractor
class CV
_
EXPORTS DescriptorExtractor
{
{
public:
public:
virtual ~DescriptorExtractor()
{}
virtual ~DescriptorExtractor();
virtual void compute( const Mat
&
image, vector<KeyPoint>
&
keypoints,
Mat
&
descriptors ) const = 0;
void compute( const vector<Mat>
&
imageCollection,
void compute( const Mat
&
image, vector<KeyPoint>
&
keypoints,
vector<vector<KeyPoint> >
&
pointCollection,
Mat
&
descriptors ) const;
vector<Mat>
&
descCollection ) const;
void compute( const vector<Mat>
&
images, vector<vector<KeyPoint> >
&
keypoints,
vector<Mat>
&
descriptors ) const;
virtual void read( const FileNode
&
)
{}
virtual void read( const FileNode
&
)
;
virtual void write( FileStorage
&
) const
{}
virtual void write( FileStorage
&
) const
;
virtual int descriptorSize() const = 0;
virtual int descriptorSize() const = 0;
virtual int descriptorType() const = 0;
virtual int descriptorType() const = 0;
...
@@ -403,15 +393,13 @@ distances between descriptors. Therefore we represent a collection of
...
@@ -403,15 +393,13 @@ distances between descriptors. Therefore we represent a collection of
descriptors as a
\cvCppCross
{
Mat
}
, where each row is one keypoint descriptor.
descriptors as a
\cvCppCross
{
Mat
}
, where each row is one keypoint descriptor.
\cvCppFunc
{
DescriptorExtractor::compute
}
\cvCppFunc
{
DescriptorExtractor::compute
}
Compute the descriptors for a set of keypoints detected in an image or image collection.
Compute the descriptors for a set of keypoints detected in an image (first variant)
or image set (second variant).
\cvdefCpp
{
\cvdefCpp
{
void DescriptorExtractor::compute( const Mat
\&
image,
void DescriptorExtractor::compute( const Mat
\&
image,
\par
vector<KeyPoint>
\&
keypoints,
\par
vector<KeyPoint>
\&
keypoints,
\par
Mat
\&
descriptors ) const;
\\
\par
Mat
\&
descriptors ) const;
void DescriptorExtractor::compute( const vector<Mat>
\&
imageCollection,
\par
vector<vector<KeyPoint> >
\&
pointCollection,
\par
vector<Mat>
\&
descCollection ) const;
}
}
\begin{description}
\begin{description}
...
@@ -420,17 +408,23 @@ void DescriptorExtractor::compute( const vector<Mat>\& imageCollection,
...
@@ -420,17 +408,23 @@ void DescriptorExtractor::compute( const vector<Mat>\& imageCollection,
\cvarg
{
descriptors
}{
The descriptors. Row i is the descriptor for keypoint i.
}
\cvarg
{
descriptors
}{
The descriptors. Row i is the descriptor for keypoint i.
}
\end{description}
\end{description}
\cvdefCpp
{
void DescriptorExtractor::compute( const vector<Mat>
\&
images,
\par
vector<vector<KeyPoint> >
\&
keypoints,
\par
vector<Mat>
\&
descriptors ) const;
}
\begin{description}
\begin{description}
\cvarg
{
image
Collection
}{
Image collection
.
}
\cvarg
{
image
s
}{
The image set
.
}
\cvarg
{
pointCollection
}{
Keypoints collection. pointCollection
[i] is keypoints
\cvarg
{
keypoints
}{
Input keypoints collection. keypoints
[i] is keypoints
detected in imageCollection
[i]. Keypoints for which a descriptor
detected in images
[i]. Keypoints for which a descriptor
can
not be computed are removed.
}
can
not be computed are removed.
}
\cvarg
{
desc
Collection
}{
Descriptor collection. descCollection[i] is descriptors
\cvarg
{
desc
riptors
}{
Descriptor collection. descriptors[i] are descriptors computed for
computed for pointCollection
[i].
}
a set keypoints
[i].
}
\end{description}
\end{description}
\cvCppFunc
{
DescriptorExtractor::read
}
\cvCppFunc
{
DescriptorExtractor::read
}
Read descriptor extractor from file node.
Read descriptor extractor
object
from file node.
\cvdefCpp
{
\cvdefCpp
{
void DescriptorExtractor::read( const FileNode
\&
fn );
void DescriptorExtractor::read( const FileNode
\&
fn );
...
@@ -441,7 +435,7 @@ void DescriptorExtractor::read( const FileNode\& fn );
...
@@ -441,7 +435,7 @@ void DescriptorExtractor::read( const FileNode\& fn );
\end{description}
\end{description}
\cvCppFunc
{
DescriptorExtractor::write
}
\cvCppFunc
{
DescriptorExtractor::write
}
Write descriptor extractor to file storage.
Write descriptor extractor
object
to file storage.
\cvdefCpp
{
\cvdefCpp
{
void DescriptorExtractor::write( FileStorage
\&
fs ) const;
void DescriptorExtractor::write( FileStorage
\&
fs ) const;
...
@@ -451,7 +445,6 @@ void DescriptorExtractor::write( FileStorage\& fs ) const;
...
@@ -451,7 +445,6 @@ void DescriptorExtractor::write( FileStorage\& fs ) const;
\cvarg
{
fs
}{
File storage in which detector will be written.
}
\cvarg
{
fs
}{
File storage in which detector will be written.
}
\end{description}
\end{description}
\cvclass
{
SiftDescriptorExtractor
}
\cvclass
{
SiftDescriptorExtractor
}
Wrapping class for descriptors computing using
\cvCppCross
{
SIFT
}
class.
Wrapping class for descriptors computing using
\cvCppCross
{
SIFT
}
class.
...
@@ -460,15 +453,13 @@ class SiftDescriptorExtractor : public DescriptorExtractor
...
@@ -460,15 +453,13 @@ class SiftDescriptorExtractor : public DescriptorExtractor
{
{
public:
public:
SiftDescriptorExtractor(
SiftDescriptorExtractor(
double magnification=SIFT::DescriptorParams::GET
_
DEFAULT
_
MAGNIFICATION(),
const SIFT::DescriptorParams
&
descriptorParams=SIFT::DescriptorParams(),
bool isNormalize=true, bool recalculateAngles=true,
const SIFT::CommonParams
&
commonParams=SIFT::CommonParams() );
int nOctaves=SIFT::CommonParams::DEFAULT
_
NOCTAVES,
SiftDescriptorExtractor( double magnification, bool isNormalize=true,
int nOctaveLayers=SIFT::CommonParams::DEFAULT
_
NOCTAVE
_
LAYERS,
bool recalculateAngles=true, int nOctaves=SIFT::CommonParams::DEFAULT
_
NOCTAVES,
int firstOctave=SIFT::CommonParams::DEFAULT
_
FIRST
_
OCTAVE,
int nOctaveLayers=SIFT::CommonParams::DEFAULT
_
NOCTAVE
_
LAYERS,
int angleMode=SIFT::CommonParams::FIRST
_
ANGLE );
int firstOctave=SIFT::CommonParams::DEFAULT
_
FIRST
_
OCTAVE,
int angleMode=SIFT::CommonParams::FIRST
_
ANGLE );
virtual void compute( const Mat
&
image, vector<KeyPoint>
&
keypoints,
Mat
&
descriptors) const;
virtual void read (const FileNode
&
fn);
virtual void read (const FileNode
&
fn);
virtual void write (FileStorage
&
fs) const;
virtual void write (FileStorage
&
fs) const;
...
@@ -489,9 +480,6 @@ public:
...
@@ -489,9 +480,6 @@ public:
SurfDescriptorExtractor( int nOctaves=4,
SurfDescriptorExtractor( int nOctaves=4,
int nOctaveLayers=2, bool extended=false );
int nOctaveLayers=2, bool extended=false );
virtual void compute( const Mat
&
image, vector<KeyPoint>
&
keypoints,
Mat
&
descriptors) const;
virtual void read (const FileNode
&
fn);
virtual void read (const FileNode
&
fn);
virtual void write (FileStorage
&
fs) const;
virtual void write (FileStorage
&
fs) const;
virtual int descriptorSize() const;
virtual int descriptorSize() const;
...
@@ -510,8 +498,6 @@ class CalonderDescriptorExtractor : public DescriptorExtractor
...
@@ -510,8 +498,6 @@ class CalonderDescriptorExtractor : public DescriptorExtractor
{
{
public:
public:
CalonderDescriptorExtractor( const string
&
classifierFile );
CalonderDescriptorExtractor( const string
&
classifierFile );
virtual void compute( const Mat
&
image, vector<KeyPoint>
&
keypoints,
Mat
&
descriptors ) const;
virtual void read( const FileNode
&
fn );
virtual void read( const FileNode
&
fn );
virtual void write( FileStorage
&
fs ) const;
virtual void write( FileStorage
&
fs ) const;
...
@@ -535,20 +521,39 @@ class OpponentColorDescriptorExtractor : public DescriptorExtractor
...
@@ -535,20 +521,39 @@ class OpponentColorDescriptorExtractor : public DescriptorExtractor
public:
public:
OpponentColorDescriptorExtractor( const Ptr<DescriptorExtractor>
&
dextractor );
OpponentColorDescriptorExtractor( const Ptr<DescriptorExtractor>
&
dextractor );
virtual void compute( const Mat
&
image, vector<KeyPoint>
&
keypoints,
Mat
&
descriptors ) const;
virtual void read( const FileNode
&
);
virtual void read( const FileNode
&
);
virtual void write( FileStorage
&
) const;
virtual void write( FileStorage
&
) const;
virtual int descriptorSize() const;
virtual int descriptorSize() const;
virtual int descriptorType() const;
virtual int descriptorType() const;
protected:
protected:
...
...
}
;
}
;
\end{lstlisting}
\end{lstlisting}
\cvclass
{
BriefDescriptorExtractor
}
Class for computing BRIEF descriptors described in paper of Calonder M., Lepetit V.,
Strecha C., Fua P.: ''BRIEF: Binary Robust Independent Elementary Features.''
11th European Conference on Computer Vision (ECCV), Heraklion, Crete. LNCS Springer, September 2010.
\begin{lstlisting}
class BriefDescriptorExtractor : public DescriptorExtractor
{
public:
static const int PATCH
_
SIZE = 48;
static const int KERNEL
_
SIZE = 9;
// bytes is a length of descriptor in bytes. It can be equal 16, 32 or 64 bytes.
BriefDescriptorExtractor( int bytes = 32 );
virtual void read( const FileNode
&
);
virtual void write( FileStorage
&
) const;
virtual int descriptorSize() const;
virtual int descriptorType() const;
protected:
...
}
;
\end{lstlisting}
\cvCppFunc
{
createDescriptorExtractor
}
\cvCppFunc
{
createDescriptorExtractor
}
Descriptor extractor factory that creates
\cvCppCross
{
DescriptorExtractor
}
of given type with
Descriptor extractor factory that creates
\cvCppCross
{
DescriptorExtractor
}
of given type with
default parameters (rather using default constructor).
default parameters (rather using default constructor).
...
@@ -559,9 +564,11 @@ createDescriptorExtractor( const string& descriptorExtractorType );
...
@@ -559,9 +564,11 @@ createDescriptorExtractor( const string& descriptorExtractorType );
\end{lstlisting}
\end{lstlisting}
\begin{description}
\begin{description}
\cvarg
{
descriptorExtractorType
}{
Descriptor extractor type
, e.g. ''SURF'', ''SIFT'', ..
.
}
\cvarg
{
descriptorExtractorType
}{
Descriptor extractor type.
}
\end{description}
\end{description}
Now the following descriptor extractor types are supported ''SIFT'', ''SURF'',
''OpponentSIFT'', ''OpponentSURF'', ''BRIEF''.
\section
{
Common Interfaces of Descriptor Matchers
}
\section
{
Common Interfaces of Descriptor Matchers
}
Matchers of keypoint descriptors in OpenCV have wrappers with common interface that enables to switch easily
Matchers of keypoint descriptors in OpenCV have wrappers with common interface that enables to switch easily
...
@@ -587,12 +594,12 @@ struct DMatch
...
@@ -587,12 +594,12 @@ struct DMatch
int queryIdx; // query descriptor index
int queryIdx; // query descriptor index
int trainIdx; // train descriptor index
int trainIdx; // train descriptor index
int imgIdx; // train image index
int imgIdx;
// train image index
float distance;
float distance;
// less is better
// less is better
bool operator<( const DMatch
&
m) const;
bool operator<( const DMatch
&
m
) const;
}
;
}
;
\end{lstlisting}
\end{lstlisting}
...
@@ -605,44 +612,47 @@ with image set.
...
@@ -605,44 +612,47 @@ with image set.
class DescriptorMatcher
class DescriptorMatcher
{
{
public:
public:
virtual ~DescriptorMatcher()
{}
virtual ~DescriptorMatcher();
virtual void add( const vector<Mat>
&
descCollection );
virtual void add( const vector<Mat>
&
descriptors );
const vector<Mat>
&
getTrainDescCollection() const;
const vector<Mat>
&
getTrainDescriptors() const;
virtual void clear();
virtual void clear();
virtual bool supportMask() = 0;
bool empty() const;
virtual bool isMaskSupported() const = 0;
virtual void train() = 0;
virtual void train();
/*
/*
* Group of methods to match descriptors from image pair.
* Group of methods to match descriptors from image pair.
*/
*/
void match( const Mat
&
queryDesc
s, const Mat
&
trainDescs,
void match( const Mat
&
queryDesc
riptors, const Mat
&
trainDescriptors,
vector<DMatch>
&
matches, const Mat
&
mask=Mat() ) const;
vector<DMatch>
&
matches, const Mat
&
mask=Mat() ) const;
void knnMatch( const Mat
&
queryDesc
s, const Mat
&
trainDescs,
void knnMatch( const Mat
&
queryDesc
riptors, const Mat
&
trainDescriptors,
vector<vector<DMatch> >
&
matches, int k
nn
,
vector<vector<DMatch> >
&
matches, int k,
const Mat
&
mask=Mat(), bool compactResult=false ) const;
const Mat
&
mask=Mat(), bool compactResult=false ) const;
void radiusMatch( const Mat
&
queryDesc
s, const Mat
&
trainDescs,
void radiusMatch( const Mat
&
queryDesc
riptors, const Mat
&
trainDescriptors,
vector<vector<DMatch> >
&
matches, float maxDistance,
vector<vector<DMatch> >
&
matches, float maxDistance,
const Mat
&
mask=Mat(), bool compactResult=false ) const;
const Mat
&
mask=Mat(), bool compactResult=false ) const;
/*
/*
* Group of methods to match descriptors from one image to image set.
* Group of methods to match descriptors from one image to image set.
*/
*/
void match( const Mat
&
queryDescs, vector<DMatch>
&
matches,
void match( const Mat
&
queryDesc
riptor
s, vector<DMatch>
&
matches,
const vector<Mat>
&
masks=vector<Mat>() );
const vector<Mat>
&
masks=vector<Mat>() );
void knnMatch( const Mat
&
queryDescs, vector<vector<DMatch> >
&
matches,
void knnMatch( const Mat
&
queryDesc
riptor
s, vector<vector<DMatch> >
&
matches,
int k
nn
, const vector<Mat>
&
masks=vector<Mat>(),
int k, const vector<Mat>
&
masks=vector<Mat>(),
bool compactResult=false );
bool compactResult=false );
void radiusMatch( const Mat
&
queryDescs, vector<vector<DMatch> >
&
matches,
void radiusMatch( const Mat
&
queryDesc
riptor
s, vector<vector<DMatch> >
&
matches,
float maxDistance, const vector<Mat>
&
masks=vector<Mat>(),
float maxDistance, const vector<Mat>
&
masks=vector<Mat>(),
bool compactResult=false );
bool compactResult=false );
virtual void read( const FileNode
&
)
{}
virtual void read( const FileNode
&
);
virtual void write( FileStorage
&
) const
{}
virtual void write( FileStorage
&
) const;
virtual Ptr<DescriptorMatcher> clone( bool emptyTrainData=false ) const = 0;
protected:
protected:
vector<Mat> trainDescCollection;
vector<Mat> trainDescCollection;
...
...
}
;
}
;
\end{lstlisting}
\end{lstlisting}
...
@@ -652,18 +662,19 @@ Add descriptors to train descriptor collection. If collection \texttt{trainDescC
...
@@ -652,18 +662,19 @@ Add descriptors to train descriptor collection. If collection \texttt{trainDescC
the new descriptors are added to existing train descriptors.
the new descriptors are added to existing train descriptors.
\cvdefCpp
{
\cvdefCpp
{
void add( const vector<Mat>
\&
desc
Collection
);
void add( const vector<Mat>
\&
desc
riptors
);
}
}
\begin{description}
\begin{description}
\cvarg
{
descCollection
}{
Descriptors to add. Each
\texttt
{
trainDescCollection[i]
}
is from the same train image.
}
\cvarg
{
descriptors
}{
Descriptors to add. Each
\texttt
{
descriptors[i]
}
is a set of descriptors
from the same (one) train image.
}
\end{description}
\end{description}
\cvCppFunc
{
DescriptorMatcher::getTrainDesc
Collection
}
\cvCppFunc
{
DescriptorMatcher::getTrainDesc
riptors
}
Returns constant link to the train descriptor collection (i.e.
\texttt
{
trainDescCollection
}
).
Returns constant link to the train descriptor collection (i.e.
\texttt
{
trainDescCollection
}
).
\cvdefCpp
{
\cvdefCpp
{
const vector<Mat>
\&
getTrainDesc
Collection
() const;
const vector<Mat>
\&
getTrainDesc
riptors
() const;
}
}
\cvCppFunc
{
DescriptorMatcher::clear
}
\cvCppFunc
{
DescriptorMatcher::clear
}
...
@@ -673,15 +684,25 @@ Clear train descriptor collection.
...
@@ -673,15 +684,25 @@ Clear train descriptor collection.
void DescriptorMatcher::clear();
void DescriptorMatcher::clear();
}
}
\cvCppFunc
{
DescriptorMatcher::supportMask
}
\cvCppFunc
{
DescriptorMatcher::empty
}
Return true if there are not train descriptors in collection.
\cvdefCpp
{
bool DescriptorMatcher::empty() const;
}
\cvCppFunc
{
DescriptorMatcher::isMaskSupported
}
Returns true if descriptor matcher supports masking permissible matches.
Returns true if descriptor matcher supports masking permissible matches.
\cvdefCpp
{
\cvdefCpp
{
bool DescriptorMatcher::
supportMask
();
bool DescriptorMatcher::
isMaskSupported
();
}
}
\cvCppFunc
{
DescriptorMatcher::train
}
\cvCppFunc
{
DescriptorMatcher::train
}
Train descriptor matcher (e.g. train flann index).
Train descriptor matcher (e.g. train flann index). In all methods to match the method train()
is run every time before matching. Some descriptor matchers (e.g. BruteForceMatcher) have empty
implementation of this method, other matchers realy train their inner structures (e.g. FlannBasedMatcher
trains flann::Index)
\cvdefCpp
{
\cvdefCpp
{
void DescriptorMatcher::train();
void DescriptorMatcher::train();
...
@@ -694,23 +715,24 @@ In first variant of this method train descriptors are set as input argument and
...
@@ -694,23 +715,24 @@ In first variant of this method train descriptors are set as input argument and
supposed that they are of keypoints detected on the same train image. In second variant
supposed that they are of keypoints detected on the same train image. In second variant
of the method train descriptors collection that was set using
\texttt
{
add
}
method is used.
of the method train descriptors collection that was set using
\texttt
{
add
}
method is used.
Optional mask (or masks) can be set to describe which descriptors can be matched.
Optional mask (or masks) can be set to describe which descriptors can be matched.
\texttt
{
descriptors
\_
1[i]
}
can be matched with
\texttt
{
descriptors
\_
2[j]
}
only if
\texttt
{
mask.at<uchar>(i,j)
}
is non-zero.
\texttt
{
queryDescriptors[i]
}
can be matched with
\texttt
{
trainDescriptors[j]
}
only if
\texttt
{
mask.at<uchar>(i,j)
}
is non-zero.
\cvdefCpp
{
\cvdefCpp
{
void DescriptorMatcher::match( const Mat
\&
queryDescs,
void DescriptorMatcher::match( const Mat
\&
queryDesc
riptor
s,
\par
const Mat
\&
trainDescs,
\par
const Mat
\&
trainDesc
riptor
s,
\par
vector<DMatch>
\&
matches,
\par
vector<DMatch>
\&
matches,
\par
const Mat
\&
mask=Mat() ) const;
\par
const Mat
\&
mask=Mat() ) const;
}
}
\cvdefCpp
{
\cvdefCpp
{
void DescriptorMatcher::match( const Mat
\&
queryDescs,
void DescriptorMatcher::match( const Mat
\&
queryDesc
riptor
s,
\par
vector<DMatch>
\&
matches,
\par
vector<DMatch>
\&
matches,
\par
const vector<Mat>
\&
masks=vector<Mat>() );
\par
const vector<Mat>
\&
masks=vector<Mat>() );
}
}
\begin{description}
\begin{description}
\cvarg
{
queryDescs
}{
Query set of descriptors.
}
\cvarg
{
queryDesc
riptor
s
}{
Query set of descriptors.
}
\cvarg
{
trainDesc
s
}{
Train set of descriptors. This will not be added to train descripo
tors collection
\cvarg
{
trainDesc
riptors
}{
Train set of descriptors. This will not be added to train descrip
tors collection
stored in class object.
}
stored in class object.
}
\cvarg
{
matches
}{
Matches. If some query descriptor masked out in
\texttt
{
mask
}
no match will be added for this descriptor.
\cvarg
{
matches
}{
Matches. If some query descriptor masked out in
\texttt
{
mask
}
no match will be added for this descriptor.
So
\texttt
{
matches
}
size may be less query descriptors count.
}
So
\texttt
{
matches
}
size may be less query descriptors count.
}
...
@@ -720,29 +742,30 @@ void DescriptorMatcher::match( const Mat\& queryDescs,
...
@@ -720,29 +742,30 @@ void DescriptorMatcher::match( const Mat\& queryDescs,
\end{description}
\end{description}
\cvCppFunc
{
DescriptorMatcher::knnMatch
}
\cvCppFunc
{
DescriptorMatcher::knnMatch
}
Find the k
nn
best matches for each descriptor from a query set with train descriptors.
Find the k best matches for each descriptor from a query set with train descriptors.
Found k
nn
(or less if not possible) matches are returned in distance increasing order.
Found k (or less if not possible) matches are returned in distance increasing order.
Details about query and train descriptors see in
\cvCppCross
{
DescriptorMatcher::match
}
.
Details about query and train descriptors see in
\cvCppCross
{
DescriptorMatcher::match
}
.
\cvdefCpp
{
\cvdefCpp
{
void DescriptorMatcher::knnMatch( const Mat
\&
queryDescs,
void DescriptorMatcher::knnMatch( const Mat
\&
queryDescriptors,
\par
const Mat
\&
trainDescs, vector<vector<DMatch> >
\&
matches,
\par
const Mat
\&
trainDescriptors,
\par
int knn, const Mat
\&
mask=Mat(),
\par
vector<vector<DMatch> >
\&
matches,
\par
int k, const Mat
\&
mask=Mat(),
\par
bool compactResult=false ) const;
\par
bool compactResult=false ) const;
}
}
\cvdefCpp
{
\cvdefCpp
{
void DescriptorMatcher::knnMatch( const Mat
\&
queryDescs,
void DescriptorMatcher::knnMatch( const Mat
\&
queryDesc
riptor
s,
\par
vector<vector<DMatch> >
\&
matches, int k
nn
,
\par
vector<vector<DMatch> >
\&
matches, int k,
\par
const vector<Mat>
\&
masks=vector<Mat>(),
\par
const vector<Mat>
\&
masks=vector<Mat>(),
\par
bool compactResult=false );
\par
bool compactResult=false );
}
}
\begin{description}
\begin{description}
\cvarg
{
queryDesc
s, trainDesc
s, mask, masks
}{
See in
\cvCppCross
{
DescriptorMatcher::match
}
.
}
\cvarg
{
queryDesc
riptors, trainDescriptor
s, mask, masks
}{
See in
\cvCppCross
{
DescriptorMatcher::match
}
.
}
\cvarg
{
matches
}{
Mathes. Each
\texttt
{
matches[i]
}
is k
nn
or less matches for the same query descriptor.
}
\cvarg
{
matches
}{
Mathes. Each
\texttt
{
matches[i]
}
is k or less matches for the same query descriptor.
}
\cvarg
{
k
nn
}{
Count of best matches will be found per each query descriptor (or less if it's not possible).
}
\cvarg
{
k
}{
Count of best matches will be found per each query descriptor (or less if it's not possible).
}
\cvarg
{
compactResult
}{
It's used when mask (or masks) is not empty. If
\texttt
{
compactResult
}
is false
\cvarg
{
compactResult
}{
It's used when mask (or masks) is not empty. If
\texttt
{
compactResult
}
is false
\texttt
{
matches
}
vector will have the same size as
\texttt
{
queryDescs
}
rows. If
\texttt
{
compactResult
}
\texttt
{
matches
}
vector will have the same size as
\texttt
{
queryDesc
riptor
s
}
rows. If
\texttt
{
compactResult
}
is true
\texttt
{
matches
}
vector will not contain matches for fully masked out query descriptors.
}
is true
\texttt
{
matches
}
vector will not contain matches for fully masked out query descriptors.
}
\end{description}
\end{description}
...
@@ -752,23 +775,38 @@ Found matches are returned in distance increasing order. Details about query and
...
@@ -752,23 +775,38 @@ Found matches are returned in distance increasing order. Details about query and
descriptors see in
\cvCppCross
{
DescriptorMatcher::match
}
.
descriptors see in
\cvCppCross
{
DescriptorMatcher::match
}
.
\cvdefCpp
{
\cvdefCpp
{
void DescriptorMatcher::radiusMatch( const Mat
\&
queryDescs,
void DescriptorMatcher::radiusMatch( const Mat
\&
queryDescriptors,
\par
const Mat
\&
trainDescs, vector<vector<DMatch> >
\&
matches,
\par
const Mat
\&
trainDescriptors,
\par
vector<vector<DMatch> >
\&
matches,
\par
float maxDistance, const Mat
\&
mask=Mat(),
\par
float maxDistance, const Mat
\&
mask=Mat(),
\par
bool compactResult=false ) const;
\par
bool compactResult=false ) const;
}
}
\cvdefCpp
{
\cvdefCpp
{
void DescriptorMatcher::radiusMatch( const Mat
\&
queryDescs,
void DescriptorMatcher::radiusMatch( const Mat
\&
queryDescriptors,
\par
vector<vector<DMatch> >
\&
matches, float maxDistance,
\par
vector<vector<DMatch> >
\&
matches,
\par
float maxDistance,
\par
const vector<Mat>
\&
masks=vector<Mat>(),
\par
const vector<Mat>
\&
masks=vector<Mat>(),
\par
bool compactResult=false );
\par
bool compactResult=false );
}
}
\begin{description}
\begin{description}
\cvarg
{
queryDesc
s, trainDesc
s, mask, masks
}{
See in
\cvCppCross
{
DescriptorMatcher::match
}
.
}
\cvarg
{
queryDesc
riptors, trainDescriptor
s, mask, masks
}{
See in
\cvCppCross
{
DescriptorMatcher::match
}
.
}
\cvarg
{
matches, compactResult
}{
See in
\cvCppCross
{
DescriptorMatcher::knnMatch
}
.
}
\cvarg
{
matches, compactResult
}{
See in
\cvCppCross
{
DescriptorMatcher::knnMatch
}
.
}
\cvarg
{
maxDistance
}{
The threshold to found match distances.
}
\cvarg
{
maxDistance
}{
The threshold to found match distances.
}
\end{description}
\end{description}
\cvCppFunc
{
DescriptorMatcher::clone
}
Clone the matcher.
\cvdefCpp
{
Ptr<DescriptorMatcher>
\\
DescriptorMatcher::clone( bool emptyTrainData ) const;
}
\begin{description}
\cvarg
{
emptyTrainData
}{
If emptyTrainData is false the method create deep copy of the object, i.e. copies
both parameters and train data. If emptyTrainData is true the method create object copy with current parameters
but with empty train data..
}
\end{description}
\cvclass
{
BruteForceMatcher
}
\cvclass
{
BruteForceMatcher
}
Brute-force descriptor matcher. For each descriptor in the first set, this matcher finds the closest
Brute-force descriptor matcher. For each descriptor in the first set, this matcher finds the closest
descriptor in the second set by trying each one. This descriptor matcher supports masking
descriptor in the second set by trying each one. This descriptor matcher supports masking
...
@@ -779,19 +817,19 @@ template<class Distance>
...
@@ -779,19 +817,19 @@ template<class Distance>
class BruteForceMatcher : public DescriptorMatcher
class BruteForceMatcher : public DescriptorMatcher
{
{
public:
public:
BruteForceMatcher( Distance d = Distance() ) : distance(d)
{}
BruteForceMatcher( Distance d = Distance() );
virtual ~BruteForceMatcher()
{}
virtual ~BruteForceMatcher();
virtual void train()
{}
virtual bool supportMask()
{
return true;
}
virtual bool isMaskSupported() const;
virtual Ptr<DescriptorMatcher> clone( bool emptyTrainData=false ) const;
protected:
protected:
...
...
}
}
\end{lstlisting}
\end{lstlisting}
For efficiency, BruteForceMatcher is templated on the distance metric.
For efficiency, BruteForceMatcher is templated on the distance metric.
For float descriptors, a common choice would be
\texttt
{
L2<float>
}
. Class
\texttt
{
L2
}
is defined as:
For float descriptors, a common choice would be
\texttt
{
L2<float>
}
. Class of supported distances are:
\begin{lstlisting}
\begin{lstlisting}
template<typename T>
template<typename T>
struct Accumulator
struct Accumulator
...
@@ -814,15 +852,42 @@ struct L2
...
@@ -814,15 +852,42 @@ struct L2
typedef typename Accumulator<T>::Type ResultType;
typedef typename Accumulator<T>::Type ResultType;
ResultType operator()( const T* a, const T* b, int size ) const;
ResultType operator()( const T* a, const T* b, int size ) const;
{
}
;
ResultType result = ResultType();
for( int i = 0; i < size; i++ )
/*
{
* Manhattan distance (city block distance) functor
ResultType diff = a[i] - b[i];
*/
result += diff*diff;
template<class T>
}
struct CV
_
EXPORTS L1
return sqrt(result);
{
}
typedef T ValueType;
typedef typename Accumulator<T>::Type ResultType;
ResultType operator()( const T* a, const T* b, int size ) const;
...
}
;
/*
* Hamming distance (city block distance) functor
*/
struct HammingLUT
{
typedef unsigned char ValueType;
typedef int ResultType;
ResultType operator()( const unsigned char* a, const unsigned char* b,
int size ) const;
...
}
;
struct Hamming
{
typedef unsigned char ValueType;
typedef int ResultType;
ResultType operator()( const unsigned char* a, const unsigned char* b,
int size ) const;
...
}
;
}
;
\end{lstlisting}
\end{lstlisting}
...
@@ -842,11 +907,13 @@ public:
...
@@ -842,11 +907,13 @@ public:
const Ptr<flann::IndexParams>
&
indexParams=new flann::KDTreeIndexParams(),
const Ptr<flann::IndexParams>
&
indexParams=new flann::KDTreeIndexParams(),
const Ptr<flann::SearchParams>
&
searchParams=new flann::SearchParams() );
const Ptr<flann::SearchParams>
&
searchParams=new flann::SearchParams() );
virtual void add( const vector<Mat>
&
desc
Collection
);
virtual void add( const vector<Mat>
&
desc
riptors
);
virtual void clear();
virtual void clear();
virtual void train();
virtual void train();
virtual bool supportMask()
{
return false;
}
virtual bool isMaskSupported() const;
virtual Ptr<DescriptorMatcher> clone( bool emptyTrainData=false ) const;
protected:
protected:
...
...
}
;
}
;
...
@@ -861,8 +928,10 @@ Ptr<DescriptorMatcher> createDescriptorMatcher( const string& descriptorMatcherT
...
@@ -861,8 +928,10 @@ Ptr<DescriptorMatcher> createDescriptorMatcher( const string& descriptorMatcherT
\end{lstlisting}
\end{lstlisting}
\begin{description}
\begin{description}
\cvarg
{
descriptorMatcherType
}{
Descriptor matcher type
, e. g. ''BruteForce'', ''FlannBased'', ..
.
}
\cvarg
{
descriptorMatcherType
}{
Descriptor matcher type.
}
\end{description}
\end{description}
Now the following matcher types are supported: ''BruteForce'' (it uses L2), ''BruteForce-L1'',
''BruteForce-Hamming'', ''BruteForce-HammingLUT''.
\section
{
Common Interfaces of Generic Descriptor Matchers
}
\section
{
Common Interfaces of Generic Descriptor Matchers
}
Matchers of keypoint descriptors in OpenCV have wrappers with common interface that enables to switch easily
Matchers of keypoint descriptors in OpenCV have wrappers with common interface that enables to switch easily
...
@@ -888,55 +957,57 @@ with image set.
...
@@ -888,55 +957,57 @@ with image set.
class GenericDescriptorMatcher
class GenericDescriptorMatcher
{
{
public:
public:
GenericDescriptorMatcher()
{}
GenericDescriptorMatcher()
;
virtual ~GenericDescriptorMatcher()
{}
virtual ~GenericDescriptorMatcher()
;
virtual void add( const vector<Mat>
&
im
gCollection
,
virtual void add( const vector<Mat>
&
im
ages
,
vector<vector<KeyPoint> >
&
pointCollection
);
vector<vector<KeyPoint> >
&
keypoints
);
const vector<Mat>
&
getTrainIm
gCollection
() const;
const vector<Mat>
&
getTrainIm
ages
() const;
const vector<vector<KeyPoint> >
&
getTrain
PointCollection
() const;
const vector<vector<KeyPoint> >
&
getTrain
Keypoints
() const;
virtual void clear();
virtual void clear();
virtual void train() = 0;
virtual void train() = 0;
virtual bool supportMask
() = 0;
virtual bool isMaskSupported
() = 0;
v
irtual v
oid classify( const Mat
&
queryImage,
void classify( const Mat
&
queryImage,
vector<KeyPoint>
&
queryP
oints,
vector<KeyPoint>
&
queryKeyp
oints,
const Mat
&
trainImage,
const Mat
&
trainImage,
vector<KeyPoint>
&
trainP
oints ) const;
vector<KeyPoint>
&
trainKeyp
oints ) const;
v
irtual v
oid classify( const Mat
&
queryImage,
void classify( const Mat
&
queryImage,
vector<KeyPoint>
&
queryP
oints );
vector<KeyPoint>
&
queryKeyp
oints );
/*
/*
* Group of methods to match keypoints from image pair.
* Group of methods to match keypoints from image pair.
*/
*/
void match( const Mat
&
queryIm
g, vector<KeyPoint>
&
queryP
oints,
void match( const Mat
&
queryIm
age, vector<KeyPoint>
&
queryKeyp
oints,
const Mat
&
trainIm
g, vector<KeyPoint>
&
trainP
oints,
const Mat
&
trainIm
age, vector<KeyPoint>
&
trainKeyp
oints,
vector<DMatch>
&
matches, const Mat
&
mask=Mat() ) const;
vector<DMatch>
&
matches, const Mat
&
mask=Mat() ) const;
void knnMatch( const Mat
&
queryIm
g, vector<KeyPoint>
&
queryP
oints,
void knnMatch( const Mat
&
queryIm
age, vector<KeyPoint>
&
queryKeyp
oints,
const Mat
&
trainIm
g, vector<KeyPoint>
&
trainP
oints,
const Mat
&
trainIm
age, vector<KeyPoint>
&
trainKeyp
oints,
vector<vector<DMatch> >
&
matches, int k
nn
,
vector<vector<DMatch> >
&
matches, int k,
const Mat
&
mask=Mat(), bool compactResult=false ) const;
const Mat
&
mask=Mat(), bool compactResult=false ) const;
void radiusMatch( const Mat
&
queryIm
g, vector<KeyPoint>
&
queryP
oints,
void radiusMatch( const Mat
&
queryIm
age, vector<KeyPoint>
&
queryKeyp
oints,
const Mat
&
trainIm
g, vector<KeyPoint>
&
trainP
oints,
const Mat
&
trainIm
age, vector<KeyPoint>
&
trainKeyp
oints,
vector<vector<DMatch> >
&
matches, float maxDistance,
vector<vector<DMatch> >
&
matches, float maxDistance,
const Mat
&
mask=Mat(), bool compactResult=false ) const;
const Mat
&
mask=Mat(), bool compactResult=false ) const;
/*
/*
* Group of methods to match keypoints from one image to image set.
* Group of methods to match keypoints from one image to image set.
*/
*/
void match( const Mat
&
queryIm
g, vector<KeyPoint>
&
queryP
oints,
void match( const Mat
&
queryIm
age, vector<KeyPoint>
&
queryKeyp
oints,
vector<DMatch>
&
matches, const vector<Mat>
&
masks=vector<Mat>() );
vector<DMatch>
&
matches, const vector<Mat>
&
masks=vector<Mat>() );
void knnMatch( const Mat
&
queryIm
g, vector<KeyPoint>
&
queryP
oints,
void knnMatch( const Mat
&
queryIm
age, vector<KeyPoint>
&
queryKeyp
oints,
vector<vector<DMatch> >
&
matches, int k
nn
,
vector<vector<DMatch> >
&
matches, int k,
const vector<Mat>
&
masks=vector<Mat>(), bool compactResult=false );
const vector<Mat>
&
masks=vector<Mat>(), bool compactResult=false );
void radiusMatch( const Mat
&
queryIm
g, vector<KeyPoint>
&
queryP
oints,
void radiusMatch( const Mat
&
queryIm
age, vector<KeyPoint>
&
queryKeyp
oints,
vector<vector<DMatch> >
&
matches, float maxDistance,
vector<vector<DMatch> >
&
matches, float maxDistance,
const vector<Mat>
&
masks=vector<Mat>(), bool compactResult=false );
const vector<Mat>
&
masks=vector<Mat>(), bool compactResult=false );
virtual void read( const FileNode
&
)
{}
virtual void read( const FileNode
&
);
virtual void write( FileStorage
&
) const
{}
virtual void write( FileStorage
&
) const;
virtual Ptr<GenericDescriptorMatcher> clone( bool emptyTrainData=false ) const = 0;
protected:
protected:
...
...
...
@@ -949,29 +1020,29 @@ If train collection is not empty new image and keypoints from them will be added
...
@@ -949,29 +1020,29 @@ If train collection is not empty new image and keypoints from them will be added
existing data.
existing data.
\cvdefCpp
{
\cvdefCpp
{
void GenericDescriptorMatcher::add( const vector<Mat>
\&
im
gCollection
,
void GenericDescriptorMatcher::add( const vector<Mat>
\&
im
ages
,
\par
vector<vector<KeyPoint> >
\&
pointCollection
);
\par
vector<vector<KeyPoint> >
\&
keypoints
);
}
}
\begin{description}
\begin{description}
\cvarg
{
im
gCollection
}{
Image collection.
}
\cvarg
{
im
ages
}{
Image collection.
}
\cvarg
{
pointCollection
}{
Point collection. Assumes that
\texttt
{
pointCollection
[i]
}
are keypoints
\cvarg
{
keypoints
}{
Point collection. Assumes that
\texttt
{
keypoints
[i]
}
are keypoints
detected in an image
\texttt
{
imgCollection
[i]
}
.
}
detected in an image
\texttt
{
images
[i]
}
.
}
\end{description}
\end{description}
\cvCppFunc
{
GenericDescriptorMatcher::getTrainIm
gCollection
}
\cvCppFunc
{
GenericDescriptorMatcher::getTrainIm
ages
}
Returns train image collection.
Returns train image collection.
\begin{lstlisting}
\begin{lstlisting}
const vector<Mat>
&
GenericDescriptorMatcher::getTrainIm
gCollection
() const;
const vector<Mat>
&
GenericDescriptorMatcher::getTrainIm
ages
() const;
\end{lstlisting}
\end{lstlisting}
\cvCppFunc
{
GenericDescriptorMatcher::getTrain
PointCollection
}
\cvCppFunc
{
GenericDescriptorMatcher::getTrain
Keypoints
}
Returns train keypoints collection.
Returns train keypoints collection.
\begin{lstlisting}
\begin{lstlisting}
const vector<vector<KeyPoint> >
&
const vector<vector<KeyPoint> >
&
GenericDescriptorMatcher::getTrain
PointCollection
() const;
GenericDescriptorMatcher::getTrain
Keypoints
() const;
\end{lstlisting}
\end{lstlisting}
\cvCppFunc
{
GenericDescriptorMatcher::clear
}
\cvCppFunc
{
GenericDescriptorMatcher::clear
}
...
@@ -989,11 +1060,11 @@ to optimize descriptors matching.
...
@@ -989,11 +1060,11 @@ to optimize descriptors matching.
void GenericDescriptorMatcher::train();
void GenericDescriptorMatcher::train();
\end{lstlisting}
\end{lstlisting}
\cvCppFunc
{
GenericDescriptorMatcher::
supportMask
}
\cvCppFunc
{
GenericDescriptorMatcher::
isMaskSupported
}
Returns true if generic descriptor matcher supports masking permissible matches.
Returns true if generic descriptor matcher supports masking permissible matches.
\begin{lstlisting}
\begin{lstlisting}
void GenericDescriptorMatcher::
supportMask
();
void GenericDescriptorMatcher::
isMaskSupported
();
\end{lstlisting}
\end{lstlisting}
\cvCppFunc
{
GenericDescriptorMatcher::classify
}
\cvCppFunc
{
GenericDescriptorMatcher::classify
}
...
@@ -1003,20 +1074,20 @@ Classifies query keypoints under keypoints of one train image qiven as input arg
...
@@ -1003,20 +1074,20 @@ Classifies query keypoints under keypoints of one train image qiven as input arg
\cvdefCpp
{
\cvdefCpp
{
void GenericDescriptorMatcher::classify(
\par
const Mat
\&
queryImage,
void GenericDescriptorMatcher::classify(
\par
const Mat
\&
queryImage,
\par
vector<KeyPoint>
\&
query
P
oints,
\par
vector<KeyPoint>
\&
query
Keyp
oints,
\par
const Mat
\&
trainImage,
\par
const Mat
\&
trainImage,
\par
vector<KeyPoint>
\&
train
P
oints ) const;
\par
vector<KeyPoint>
\&
train
Keyp
oints ) const;
}
}
\cvdefCpp
{
\cvdefCpp
{
void GenericDescriptorMatcher::classify( const Mat
\&
queryImage,
void GenericDescriptorMatcher::classify( const Mat
\&
queryImage,
\par
vector<KeyPoint>
\&
query
P
oints );
\par
vector<KeyPoint>
\&
query
Keyp
oints );
}
}
\begin{description}
\begin{description}
\cvarg
{
queryImage
}{
The query image.
}
\cvarg
{
queryImage
}{
The query image.
}
\cvarg
{
query
P
oints
}{
Keypoints from the query image.
}
\cvarg
{
query
Keyp
oints
}{
Keypoints from the query image.
}
\cvarg
{
trainImage
}{
The train image.
}
\cvarg
{
trainImage
}{
The train image.
}
\cvarg
{
train
P
oints
}{
Keypoints from the train image.
}
\cvarg
{
train
Keyp
oints
}{
Keypoints from the train image.
}
\end{description}
\end{description}
\cvCppFunc
{
GenericDescriptorMatcher::match
}
\cvCppFunc
{
GenericDescriptorMatcher::match
}
...
@@ -1028,24 +1099,24 @@ the mask can be set.
...
@@ -1028,24 +1099,24 @@ the mask can be set.
\cvdefCpp
{
\cvdefCpp
{
void GenericDescriptorMatcher::match(
void GenericDescriptorMatcher::match(
\par
const Mat
\&
queryIm
g, vector<KeyPoint>
\&
queryP
oints,
\par
const Mat
\&
queryIm
age, vector<KeyPoint>
\&
queryKeyp
oints,
\par
const Mat
\&
trainIm
g, vector<KeyPoint>
\&
trainP
oints,
\par
const Mat
\&
trainIm
age, vector<KeyPoint>
\&
trainKeyp
oints,
\par
vector<DMatch>
\&
matches, const Mat
\&
mask=Mat() ) const;
\par
vector<DMatch>
\&
matches, const Mat
\&
mask=Mat() ) const;
}
}
\cvdefCpp
{
\cvdefCpp
{
void GenericDescriptorMatcher::match(
void GenericDescriptorMatcher::match(
\par
const Mat
\&
queryIm
g, vector<KeyPoint>
\&
queryP
oints,
\par
const Mat
\&
queryIm
age, vector<KeyPoint>
\&
queryKeyp
oints,
\par
vector<DMatch>
\&
matches,
\par
vector<DMatch>
\&
matches,
\par
const vector<Mat>
\&
masks=vector<Mat>() );
\par
const vector<Mat>
\&
masks=vector<Mat>() );
}
}
\begin{description}
\begin{description}
\cvarg
{
queryIm
g
}{
Query image.
}
\cvarg
{
queryIm
age
}{
Query image.
}
\cvarg
{
query
Points
}{
Keypoints detected in
\texttt
{
queryImg
}
.
}
\cvarg
{
query
Keypoints
}{
Keypoints detected in
\texttt
{
queryImage
}
.
}
\cvarg
{
trainIm
g
}{
Train image. This will not be added to train image collection
\cvarg
{
trainIm
age
}{
Train image. This will not be added to train image collection
stored in class object.
}
stored in class object.
}
\cvarg
{
train
Points
}{
Keypoints detected in
\texttt
{
trainImg
}
. They will not be added to train points collection
\cvarg
{
train
Keypoints
}{
Keypoints detected in
\texttt
{
trainImage
}
. They will not be added to train points collection
stored in class object.
}
stored in class object.
}
\cvarg
{
matches
}{
Matches. If some query descriptor (keypoint) masked out in
\texttt
{
mask
}
\cvarg
{
matches
}{
Matches. If some query descriptor (keypoint) masked out in
\texttt
{
mask
}
no match will be added for this descriptor.
no match will be added for this descriptor.
...
@@ -1063,16 +1134,16 @@ Details see in \cvCppCross{GenericDescriptorMatcher::match} and \cvCppCross{Desc
...
@@ -1063,16 +1134,16 @@ Details see in \cvCppCross{GenericDescriptorMatcher::match} and \cvCppCross{Desc
\cvdefCpp
{
\cvdefCpp
{
void GenericDescriptorMatcher::knnMatch(
void GenericDescriptorMatcher::knnMatch(
\par
const Mat
\&
queryIm
g, vector<KeyPoint>
\&
queryP
oints,
\par
const Mat
\&
queryIm
age, vector<KeyPoint>
\&
queryKeyp
oints,
\par
const Mat
\&
trainIm
g, vector<KeyPoint>
\&
trainP
oints,
\par
const Mat
\&
trainIm
age, vector<KeyPoint>
\&
trainKeyp
oints,
\par
vector<vector<DMatch> >
\&
matches, int k
nn
,
\par
vector<vector<DMatch> >
\&
matches, int k,
\par
const Mat
\&
mask=Mat(), bool compactResult=false ) const;
\par
const Mat
\&
mask=Mat(), bool compactResult=false ) const;
}
}
\cvdefCpp
{
\cvdefCpp
{
void GenericDescriptorMatcher::knnMatch(
void GenericDescriptorMatcher::knnMatch(
\par
const Mat
\&
queryIm
g, vector<KeyPoint>
\&
queryP
oints,
\par
const Mat
\&
queryIm
age, vector<KeyPoint>
\&
queryKeyp
oints,
\par
vector<vector<DMatch> >
\&
matches, int k
nn
,
\par
vector<vector<DMatch> >
\&
matches, int k,
\par
const vector<Mat>
\&
masks=vector<Mat>(),
\par
const vector<Mat>
\&
masks=vector<Mat>(),
\par
bool compactResult=false );
\par
bool compactResult=false );
}
}
...
@@ -1084,8 +1155,8 @@ Found matches are returned in distance increasing order. Details see in
...
@@ -1084,8 +1155,8 @@ Found matches are returned in distance increasing order. Details see in
\cvdefCpp
{
\cvdefCpp
{
void GenericDescriptorMatcher::radiusMatch(
void GenericDescriptorMatcher::radiusMatch(
\par
const Mat
\&
queryIm
g, vector<KeyPoint>
\&
queryP
oints,
\par
const Mat
\&
queryIm
age, vector<KeyPoint>
\&
queryKeyp
oints,
\par
const Mat
\&
trainIm
g, vector<KeyPoint>
\&
trainP
oints,
\par
const Mat
\&
trainIm
age, vector<KeyPoint>
\&
trainKeyp
oints,
\par
vector<vector<DMatch> >
\&
matches, float maxDistance,
\par
vector<vector<DMatch> >
\&
matches, float maxDistance,
\par
const Mat
\&
mask=Mat(), bool compactResult=false ) const;
\par
const Mat
\&
mask=Mat(), bool compactResult=false ) const;
...
@@ -1093,7 +1164,7 @@ void GenericDescriptorMatcher::radiusMatch(
...
@@ -1093,7 +1164,7 @@ void GenericDescriptorMatcher::radiusMatch(
}
}
\cvdefCpp
{
\cvdefCpp
{
void GenericDescriptorMatcher::radiusMatch(
void GenericDescriptorMatcher::radiusMatch(
\par
const Mat
\&
queryIm
g, vector<KeyPoint>
\&
queryP
oints,
\par
const Mat
\&
queryIm
age, vector<KeyPoint>
\&
queryKeyp
oints,
\par
vector<vector<DMatch> >
\&
matches, float maxDistance,
\par
vector<vector<DMatch> >
\&
matches, float maxDistance,
\par
const vector<Mat>
\&
masks=vector<Mat>(),
\par
const vector<Mat>
\&
masks=vector<Mat>(),
\par
bool compactResult=false );
\par
bool compactResult=false );
...
@@ -1113,6 +1184,20 @@ Writes match object to a file storage
...
@@ -1113,6 +1184,20 @@ Writes match object to a file storage
void GenericDescriptorMatcher::write( FileStorage
\&
fs ) const;
void GenericDescriptorMatcher::write( FileStorage
\&
fs ) const;
}
}
\cvCppFunc
{
GenericDescriptorMatcher::clone
}
Clone the matcher.
\cvdefCpp
{
Ptr<GenericDescriptorMatcher>
\\
GenericDescriptorMatcher::clone( bool emptyTrainData ) const;
}
\begin{description}
\cvarg
{
emptyTrainData
}{
If emptyTrainData is false the method create deep copy of the object, i.e. copies
both parameters and train data. If emptyTrainData is true the method create object copy with current parameters
but with empty train data.
}
\end{description}
\cvclass
{
OneWayDescriptorMatcher
}
\cvclass
{
OneWayDescriptorMatcher
}
Wrapping class for computing, matching and classification of descriptors using
\cvCppCross
{
OneWayDescriptorBase
}
class.
Wrapping class for computing, matching and classification of descriptors using
\cvCppCross
{
OneWayDescriptorBase
}
class.
...
@@ -1130,16 +1215,12 @@ public:
...
@@ -1130,16 +1215,12 @@ public:
static float GET
_
MAX
_
SCALE()
{
return 1.5f;
}
static float GET
_
MAX
_
SCALE()
{
return 1.5f;
}
static float GET
_
STEP
_
SCALE()
{
return 1.2f;
}
static float GET
_
STEP
_
SCALE()
{
return 1.2f;
}
Params( int
_
poseCount = POSE
_
COUNT,
Params( int poseCount = POSE
_
COUNT,
Size
_
patchSize = Size(PATCH
_
WIDTH, PATCH
_
HEIGHT),
Size patchSize = Size(PATCH
_
WIDTH, PATCH
_
HEIGHT),
string
_
pcaFilename = string(),
string pcaFilename = string(),
string
_
trainPath = string(),
string trainPath = string(), string trainImagesList = string(),
string
_
trainImagesList = string(),
float minScale = GET
_
MIN
_
SCALE(), float maxScale = GET
_
MAX
_
SCALE(),
float
_
minScale = GET
_
MIN
_
SCALE(), float
_
maxScale = GET
_
MAX
_
SCALE(),
float stepScale = GET
_
STEP
_
SCALE() );
float
_
stepScale = GET
_
STEP
_
SCALE() ) :
poseCount(
_
poseCount), patchSize(
_
patchSize), pcaFilename(
_
pcaFilename),
trainPath(
_
trainPath), trainImagesList(
_
trainImagesList),
minScale(
_
minScale), maxScale(
_
maxScale), stepScale(
_
stepScale)
{}
int poseCount;
int poseCount;
Size patchSize;
Size patchSize;
...
@@ -1150,21 +1231,22 @@ public:
...
@@ -1150,21 +1231,22 @@ public:
float minScale, maxScale, stepScale;
float minScale, maxScale, stepScale;
}
;
}
;
// Equivalent to calling PointMatchOneWay() followed by Initialize(
_
params)
OneWayDescriptorMatcher( const Params
&
params=Params() );
OneWayDescriptorMatcher( const Params
&
_
params=Params() );
virtual ~OneWayDescriptorMatcher();
virtual ~OneWayDescriptorMatcher();
void initialize( const Params
&
_
params,
void initialize( const Params
&
params, const Ptr<OneWayDescriptorBase>
&
base=Ptr<OneWayDescriptorBase>() );
const Ptr<OneWayDescriptorBase>
&
_
base=Ptr<OneWayDescriptorBase>() );
virtual void clear ();
// Clears keypoints storing in collection and OneWayDescriptorBase
virtual void train();
virtual void clear();
virtual void train();
virtual bool
supportMask()
{
return false;
}
virtual bool
isMaskSupported();
virtual void read( const FileNode
&
fn );
virtual void read( const FileNode
&
fn );
virtual void write( FileStorage
&
fs ) const;
virtual void write( FileStorage
&
fs ) const;
virtual Ptr<GenericDescriptorMatcher> clone( bool emptyTrainData=false ) const;
protected:
protected:
...
...
}
;
}
;
...
@@ -1180,16 +1262,16 @@ public:
...
@@ -1180,16 +1262,16 @@ public:
class Params
class Params
{
{
public:
public:
Params( int
_
nclasses=0,
Params( int nclasses=0,
int
_
patchSize=FernClassifier::PATCH
_
SIZE,
int patchSize=FernClassifier::PATCH
_
SIZE,
int
_
signatureSize=FernClassifier::DEFAULT
_
SIGNATURE
_
SIZE,
int signatureSize=FernClassifier::DEFAULT
_
SIGNATURE
_
SIZE,
int
_
nstructs=FernClassifier::DEFAULT
_
STRUCTS,
int nstructs=FernClassifier::DEFAULT
_
STRUCTS,
int
_
structSize=FernClassifier::DEFAULT
_
STRUCT
_
SIZE,
int structSize=FernClassifier::DEFAULT
_
STRUCT
_
SIZE,
int
_
nviews=FernClassifier::DEFAULT
_
VIEWS,
int nviews=FernClassifier::DEFAULT
_
VIEWS,
int
_
compressionMethod=FernClassifier::COMPRESSION
_
NONE,
int compressionMethod=FernClassifier::COMPRESSION
_
NONE,
const PatchGenerator
&
patchGenerator=PatchGenerator() );
const PatchGenerator
&
patchGenerator=PatchGenerator() );
Params( const string
&
_
filename );
Params( const string
&
filename );
int nclasses;
int nclasses;
int patchSize;
int patchSize;
...
@@ -1203,18 +1285,20 @@ public:
...
@@ -1203,18 +1285,20 @@ public:
string filename;
string filename;
}
;
}
;
FernDescriptorMatcher( const Params
&
_
params=Params() );
FernDescriptorMatcher( const Params
&
params=Params() );
virtual ~FernDescriptorMatcher();
virtual ~FernDescriptorMatcher();
virtual void clear();
virtual void clear();
virtual void train();
virtual void train();
virtual bool
supportMask()
{
return false;
}
virtual bool
isMaskSupported();
virtual void read( const FileNode
&
fn );
virtual void read( const FileNode
&
fn );
virtual void write( FileStorage
&
fs ) const;
virtual void write( FileStorage
&
fs ) const;
virtual Ptr<GenericDescriptorMatcher> clone( bool emptyTrainData=false ) const;
protected:
protected:
...
...
}
;
}
;
...
@@ -1224,28 +1308,23 @@ protected:
...
@@ -1224,28 +1308,23 @@ protected:
Class used for matching descriptors that can be described as vectors in a finite-dimensional space.
Class used for matching descriptors that can be described as vectors in a finite-dimensional space.
\begin{lstlisting}
\begin{lstlisting}
class VectorDescriptorMatcher : public GenericDescriptorMatcher
class
CV
_
EXPORTS
VectorDescriptorMatcher : public GenericDescriptorMatcher
{
{
public:
public:
VectorDescriptorMatcher( const Ptr<DescriptorExtractor>
&
_
extractor,
VectorDescriptorMatcher( const Ptr<DescriptorExtractor>
&
extractor, const Ptr<DescriptorMatcher>
&
matcher );
const Ptr<DescriptorMatcher>
&
_
matcher )
virtual ~VectorDescriptorMatcher();
: extractor(
_
extractor ), matcher(
_
matcher )
{
CV
_
Assert( !extractor.empty()
&&
!matcher.empty() );
}
virtual ~VectorDescriptorMatcher()
{}
virtual void add( const vector<Mat>
&
imgCollection,
virtual void add( const vector<Mat>
&
imgCollection,
vector<vector<KeyPoint> >
&
pointCollection );
vector<vector<KeyPoint> >
&
pointCollection );
virtual void clear();
virtual void clear();
virtual void train();
virtual void train();
virtual bool isMaskSupported();
virtual bool supportMask()
{
matcher->supportMask();
}
virtual void read( const FileNode
&
fn );
virtual void read( const FileNode
&
fn );
virtual void write( FileStorage
&
fs ) const;
virtual void write( FileStorage
&
fs ) const;
virtual Ptr<GenericDescriptorMatcher> clone( bool emptyTrainData=false ) const;
protected:
protected:
...
...
}
;
}
;
...
...
modules/features2d/include/opencv2/features2d/features2d.hpp
View file @
c6e43c38
...
@@ -1448,9 +1448,9 @@ protected:
...
@@ -1448,9 +1448,9 @@ protected:
int
levels
;
int
levels
;
};
};
/*
***************************************************************************************\
/*
* Dynamic Feature Detectors *
* Dynamic Feature Detectors
\***************************************************************************************
*/
*/
/** \brief an adaptively adjusting detector that iteratively detects until the desired number
/** \brief an adaptively adjusting detector that iteratively detects until the desired number
* of features are detected.
* of features are detected.
* Beware that this is not thread safe - as the adjustment of parameters breaks the const
* Beware that this is not thread safe - as the adjustment of parameters breaks the const
...
@@ -1473,9 +1473,9 @@ public:
...
@@ -1473,9 +1473,9 @@ public:
max_features
),
adjuster_
(
a
)
{
max_features
),
adjuster_
(
a
)
{
}
}
protected
:
protected
:
virtual
void
detectImpl
(
const
cv
::
Mat
&
image
,
virtual
void
detectImpl
(
const
cv
::
Mat
&
image
,
std
::
vector
<
cv
::
KeyPoint
>&
keypoints
,
const
cv
::
Mat
&
mask
=
std
::
vector
<
cv
::
KeyPoint
>&
keypoints
,
const
cv
::
Mat
&
mask
=
cv
::
Mat
())
const
{
cv
::
Mat
())
const
{
//for oscillation testing
//for oscillation testing
bool
down
=
false
;
bool
down
=
false
;
bool
up
=
false
;
bool
up
=
false
;
...
@@ -1630,7 +1630,7 @@ public:
...
@@ -1630,7 +1630,7 @@ public:
* images Image collection.
* images Image collection.
* keypoints Input keypoints collection. keypoints[i] is keypoints detected in images[i].
* keypoints Input keypoints collection. keypoints[i] is keypoints detected in images[i].
* Keypoints for which a descriptor cannot be computed are removed.
* Keypoints for which a descriptor cannot be computed are removed.
* descriptors Descriptor collection. descriptors[i]
is descriptors computed for
keypoints[i].
* descriptors Descriptor collection. descriptors[i]
are descriptors computed for set
keypoints[i].
*/
*/
void
compute
(
const
vector
<
Mat
>&
images
,
vector
<
vector
<
KeyPoint
>
>&
keypoints
,
vector
<
Mat
>&
descriptors
)
const
;
void
compute
(
const
vector
<
Mat
>&
images
,
vector
<
vector
<
KeyPoint
>
>&
keypoints
,
vector
<
Mat
>&
descriptors
)
const
;
...
@@ -1788,7 +1788,8 @@ public:
...
@@ -1788,7 +1788,8 @@ public:
static
const
int
PATCH_SIZE
=
48
;
static
const
int
PATCH_SIZE
=
48
;
static
const
int
KERNEL_SIZE
=
9
;
static
const
int
KERNEL_SIZE
=
9
;
BriefDescriptorExtractor
(
int
bytes
=
32
);
// bytes is a length of descriptor in bytes. It can be equal 16, 32 or 64 bytes.
BriefDescriptorExtractor
(
int
bytes
=
32
);
virtual
int
descriptorSize
()
const
;
virtual
int
descriptorSize
()
const
;
virtual
int
descriptorType
()
const
;
virtual
int
descriptorType
()
const
;
...
@@ -1893,7 +1894,7 @@ struct CV_EXPORTS HammingLUT
...
@@ -1893,7 +1894,7 @@ struct CV_EXPORTS HammingLUT
/// @todo Variable-length version, maybe default size=0 and specialize
/// @todo Variable-length version, maybe default size=0 and specialize
/// @todo Need to choose C/SSE4 at runtime, but amortize this at matcher level for efficiency...
/// @todo Need to choose C/SSE4 at runtime, but amortize this at matcher level for efficiency...
struct
Hamming
struct
CV_EXPORTS
Hamming
{
{
typedef
unsigned
char
ValueType
;
typedef
unsigned
char
ValueType
;
typedef
int
ResultType
;
typedef
int
ResultType
;
...
@@ -1936,7 +1937,7 @@ struct CV_EXPORTS DMatch
...
@@ -1936,7 +1937,7 @@ struct CV_EXPORTS DMatch
float
distance
;
float
distance
;
// less is better
// less is better
bool
operator
<
(
const
DMatch
&
m
)
const
bool
operator
<
(
const
DMatch
&
m
)
const
{
{
return
distance
<
m
.
distance
;
return
distance
<
m
.
distance
;
}
}
...
@@ -2370,10 +2371,10 @@ public:
...
@@ -2370,10 +2371,10 @@ public:
* trainKeypoints Keypoints from the train image
* trainKeypoints Keypoints from the train image
*/
*/
// Classify keypoints from query image under one train image.
// Classify keypoints from query image under one train image.
v
irtual
v
oid
classify
(
const
Mat
&
queryImage
,
vector
<
KeyPoint
>&
queryKeypoints
,
void
classify
(
const
Mat
&
queryImage
,
vector
<
KeyPoint
>&
queryKeypoints
,
const
Mat
&
trainImage
,
vector
<
KeyPoint
>&
trainKeypoints
)
const
;
const
Mat
&
trainImage
,
vector
<
KeyPoint
>&
trainKeypoints
)
const
;
// Classify keypoints from query image under train image collection.
// Classify keypoints from query image under train image collection.
v
irtual
v
oid
classify
(
const
Mat
&
queryImage
,
vector
<
KeyPoint
>&
queryKeypoints
);
void
classify
(
const
Mat
&
queryImage
,
vector
<
KeyPoint
>&
queryKeypoints
);
/*
/*
* Group of methods to match keypoints from image pair.
* Group of methods to match keypoints from image pair.
...
...
modules/features2d/src/descriptors.cpp
View file @
c6e43c38
...
@@ -84,6 +84,7 @@ void DescriptorExtractor::compute( const Mat& image, vector<KeyPoint>& keypoints
...
@@ -84,6 +84,7 @@ void DescriptorExtractor::compute( const Mat& image, vector<KeyPoint>& keypoints
void
DescriptorExtractor
::
compute
(
const
vector
<
Mat
>&
imageCollection
,
vector
<
vector
<
KeyPoint
>
>&
pointCollection
,
vector
<
Mat
>&
descCollection
)
const
void
DescriptorExtractor
::
compute
(
const
vector
<
Mat
>&
imageCollection
,
vector
<
vector
<
KeyPoint
>
>&
pointCollection
,
vector
<
Mat
>&
descCollection
)
const
{
{
CV_Assert
(
imageCollection
.
size
()
==
pointCollection
.
size
()
);
descCollection
.
resize
(
imageCollection
.
size
()
);
descCollection
.
resize
(
imageCollection
.
size
()
);
for
(
size_t
i
=
0
;
i
<
imageCollection
.
size
();
i
++
)
for
(
size_t
i
=
0
;
i
<
imageCollection
.
size
();
i
++
)
compute
(
imageCollection
[
i
],
pointCollection
[
i
],
descCollection
[
i
]
);
compute
(
imageCollection
[
i
],
pointCollection
[
i
],
descCollection
[
i
]
);
...
...
modules/features2d/src/matchers.cpp
View file @
c6e43c38
...
@@ -591,7 +591,11 @@ void FlannBasedMatcher::radiusMatchImpl( const Mat& queryDescriptors, vector<vec
...
@@ -591,7 +591,11 @@ void FlannBasedMatcher::radiusMatchImpl( const Mat& queryDescriptors, vector<vec
Ptr
<
DescriptorMatcher
>
createDescriptorMatcher
(
const
string
&
descriptorMatcherType
)
Ptr
<
DescriptorMatcher
>
createDescriptorMatcher
(
const
string
&
descriptorMatcherType
)
{
{
DescriptorMatcher
*
dm
=
0
;
DescriptorMatcher
*
dm
=
0
;
if
(
!
descriptorMatcherType
.
compare
(
"BruteForce"
)
)
if
(
!
descriptorMatcherType
.
compare
(
"FlannBased"
)
)
{
dm
=
new
FlannBasedMatcher
();
}
else
if
(
!
descriptorMatcherType
.
compare
(
"BruteForce"
)
)
// L2
{
{
dm
=
new
BruteForceMatcher
<
L2
<
float
>
>
();
dm
=
new
BruteForceMatcher
<
L2
<
float
>
>
();
}
}
...
@@ -599,21 +603,13 @@ Ptr<DescriptorMatcher> createDescriptorMatcher( const string& descriptorMatcherT
...
@@ -599,21 +603,13 @@ Ptr<DescriptorMatcher> createDescriptorMatcher( const string& descriptorMatcherT
{
{
dm
=
new
BruteForceMatcher
<
L1
<
float
>
>
();
dm
=
new
BruteForceMatcher
<
L1
<
float
>
>
();
}
}
else
if
(
!
descriptorMatcherType
.
compare
(
"FlannBased"
)
)
else
if
(
!
descriptorMatcherType
.
compare
(
"BruteForce-Hamming"
)
)
{
{
dm
=
new
FlannBasedMatcher
();
dm
=
new
BruteForceMatcher
<
Hamming
>
();
}
}
else
if
(
!
descriptorMatcherType
.
compare
(
"BruteForce-Hamming"
))
else
if
(
!
descriptorMatcherType
.
compare
(
"BruteForce-HammingLUT"
)
)
{
dm
=
new
BruteForceMatcher
<
Hamming
>
();
}
else
if
(
!
descriptorMatcherType
.
compare
(
"BruteForce-HammingLUT"
))
{
dm
=
new
BruteForceMatcher
<
HammingLUT
>
();
}
else
{
{
//CV_Error( CV_StsBadArg, "unsupported descriptor matcher type"
);
dm
=
new
BruteForceMatcher
<
HammingLUT
>
(
);
}
}
return
dm
;
return
dm
;
...
@@ -766,83 +762,83 @@ void GenericDescriptorMatcher::clear()
...
@@ -766,83 +762,83 @@ void GenericDescriptorMatcher::clear()
void
GenericDescriptorMatcher
::
train
()
void
GenericDescriptorMatcher
::
train
()
{}
{}
void
GenericDescriptorMatcher
::
classify
(
const
Mat
&
queryImage
,
vector
<
KeyPoint
>&
query
P
oints
,
void
GenericDescriptorMatcher
::
classify
(
const
Mat
&
queryImage
,
vector
<
KeyPoint
>&
query
Keyp
oints
,
const
Mat
&
trainImage
,
vector
<
KeyPoint
>&
train
P
oints
)
const
const
Mat
&
trainImage
,
vector
<
KeyPoint
>&
train
Keyp
oints
)
const
{
{
vector
<
DMatch
>
matches
;
vector
<
DMatch
>
matches
;
match
(
queryImage
,
query
Points
,
trainImage
,
trainP
oints
,
matches
);
match
(
queryImage
,
query
Keypoints
,
trainImage
,
trainKeyp
oints
,
matches
);
// remap keypoint indices to descriptors
// remap keypoint indices to descriptors
for
(
size_t
i
=
0
;
i
<
matches
.
size
();
i
++
)
for
(
size_t
i
=
0
;
i
<
matches
.
size
();
i
++
)
query
Points
[
matches
[
i
].
queryIdx
].
class_id
=
trainP
oints
[
matches
[
i
].
trainIdx
].
class_id
;
query
Keypoints
[
matches
[
i
].
queryIdx
].
class_id
=
trainKeyp
oints
[
matches
[
i
].
trainIdx
].
class_id
;
}
}
void
GenericDescriptorMatcher
::
classify
(
const
Mat
&
queryImage
,
vector
<
KeyPoint
>&
query
P
oints
)
void
GenericDescriptorMatcher
::
classify
(
const
Mat
&
queryImage
,
vector
<
KeyPoint
>&
query
Keyp
oints
)
{
{
vector
<
DMatch
>
matches
;
vector
<
DMatch
>
matches
;
match
(
queryImage
,
query
P
oints
,
matches
);
match
(
queryImage
,
query
Keyp
oints
,
matches
);
// remap keypoint indices to descriptors
// remap keypoint indices to descriptors
for
(
size_t
i
=
0
;
i
<
matches
.
size
();
i
++
)
for
(
size_t
i
=
0
;
i
<
matches
.
size
();
i
++
)
query
P
oints
[
matches
[
i
].
queryIdx
].
class_id
=
trainPointCollection
.
getKeyPoint
(
matches
[
i
].
trainIdx
,
matches
[
i
].
trainIdx
).
class_id
;
query
Keyp
oints
[
matches
[
i
].
queryIdx
].
class_id
=
trainPointCollection
.
getKeyPoint
(
matches
[
i
].
trainIdx
,
matches
[
i
].
trainIdx
).
class_id
;
}
}
void
GenericDescriptorMatcher
::
match
(
const
Mat
&
queryIm
g
,
vector
<
KeyPoint
>&
queryP
oints
,
void
GenericDescriptorMatcher
::
match
(
const
Mat
&
queryIm
age
,
vector
<
KeyPoint
>&
queryKeyp
oints
,
const
Mat
&
trainIm
g
,
vector
<
KeyPoint
>&
trainP
oints
,
const
Mat
&
trainIm
age
,
vector
<
KeyPoint
>&
trainKeyp
oints
,
vector
<
DMatch
>&
matches
,
const
Mat
&
mask
)
const
vector
<
DMatch
>&
matches
,
const
Mat
&
mask
)
const
{
{
Ptr
<
GenericDescriptorMatcher
>
tempMatcher
=
clone
(
true
);
Ptr
<
GenericDescriptorMatcher
>
tempMatcher
=
clone
(
true
);
vector
<
vector
<
KeyPoint
>
>
vecTrainPoints
(
1
,
train
P
oints
);
vector
<
vector
<
KeyPoint
>
>
vecTrainPoints
(
1
,
train
Keyp
oints
);
tempMatcher
->
add
(
vector
<
Mat
>
(
1
,
trainIm
g
),
vecTrainPoints
);
tempMatcher
->
add
(
vector
<
Mat
>
(
1
,
trainIm
age
),
vecTrainPoints
);
tempMatcher
->
match
(
queryIm
g
,
queryP
oints
,
matches
,
vector
<
Mat
>
(
1
,
mask
)
);
tempMatcher
->
match
(
queryIm
age
,
queryKeyp
oints
,
matches
,
vector
<
Mat
>
(
1
,
mask
)
);
vecTrainPoints
[
0
].
swap
(
train
P
oints
);
vecTrainPoints
[
0
].
swap
(
train
Keyp
oints
);
}
}
void
GenericDescriptorMatcher
::
knnMatch
(
const
Mat
&
queryIm
g
,
vector
<
KeyPoint
>&
queryP
oints
,
void
GenericDescriptorMatcher
::
knnMatch
(
const
Mat
&
queryIm
age
,
vector
<
KeyPoint
>&
queryKeyp
oints
,
const
Mat
&
trainIm
g
,
vector
<
KeyPoint
>&
trainP
oints
,
const
Mat
&
trainIm
age
,
vector
<
KeyPoint
>&
trainKeyp
oints
,
vector
<
vector
<
DMatch
>
>&
matches
,
int
knn
,
const
Mat
&
mask
,
bool
compactResult
)
const
vector
<
vector
<
DMatch
>
>&
matches
,
int
knn
,
const
Mat
&
mask
,
bool
compactResult
)
const
{
{
Ptr
<
GenericDescriptorMatcher
>
tempMatcher
=
clone
(
true
);
Ptr
<
GenericDescriptorMatcher
>
tempMatcher
=
clone
(
true
);
vector
<
vector
<
KeyPoint
>
>
vecTrainPoints
(
1
,
train
P
oints
);
vector
<
vector
<
KeyPoint
>
>
vecTrainPoints
(
1
,
train
Keyp
oints
);
tempMatcher
->
add
(
vector
<
Mat
>
(
1
,
trainIm
g
),
vecTrainPoints
);
tempMatcher
->
add
(
vector
<
Mat
>
(
1
,
trainIm
age
),
vecTrainPoints
);
tempMatcher
->
knnMatch
(
queryIm
g
,
queryP
oints
,
matches
,
knn
,
vector
<
Mat
>
(
1
,
mask
),
compactResult
);
tempMatcher
->
knnMatch
(
queryIm
age
,
queryKeyp
oints
,
matches
,
knn
,
vector
<
Mat
>
(
1
,
mask
),
compactResult
);
vecTrainPoints
[
0
].
swap
(
train
P
oints
);
vecTrainPoints
[
0
].
swap
(
train
Keyp
oints
);
}
}
void
GenericDescriptorMatcher
::
radiusMatch
(
const
Mat
&
queryIm
g
,
vector
<
KeyPoint
>&
queryP
oints
,
void
GenericDescriptorMatcher
::
radiusMatch
(
const
Mat
&
queryIm
age
,
vector
<
KeyPoint
>&
queryKeyp
oints
,
const
Mat
&
trainIm
g
,
vector
<
KeyPoint
>&
trainP
oints
,
const
Mat
&
trainIm
age
,
vector
<
KeyPoint
>&
trainKeyp
oints
,
vector
<
vector
<
DMatch
>
>&
matches
,
float
maxDistance
,
vector
<
vector
<
DMatch
>
>&
matches
,
float
maxDistance
,
const
Mat
&
mask
,
bool
compactResult
)
const
const
Mat
&
mask
,
bool
compactResult
)
const
{
{
Ptr
<
GenericDescriptorMatcher
>
tempMatcher
=
clone
(
true
);
Ptr
<
GenericDescriptorMatcher
>
tempMatcher
=
clone
(
true
);
vector
<
vector
<
KeyPoint
>
>
vecTrainPoints
(
1
,
train
P
oints
);
vector
<
vector
<
KeyPoint
>
>
vecTrainPoints
(
1
,
train
Keyp
oints
);
tempMatcher
->
add
(
vector
<
Mat
>
(
1
,
trainIm
g
),
vecTrainPoints
);
tempMatcher
->
add
(
vector
<
Mat
>
(
1
,
trainIm
age
),
vecTrainPoints
);
tempMatcher
->
radiusMatch
(
queryIm
g
,
queryP
oints
,
matches
,
maxDistance
,
vector
<
Mat
>
(
1
,
mask
),
compactResult
);
tempMatcher
->
radiusMatch
(
queryIm
age
,
queryKeyp
oints
,
matches
,
maxDistance
,
vector
<
Mat
>
(
1
,
mask
),
compactResult
);
vecTrainPoints
[
0
].
swap
(
train
P
oints
);
vecTrainPoints
[
0
].
swap
(
train
Keyp
oints
);
}
}
void
GenericDescriptorMatcher
::
match
(
const
Mat
&
queryIm
g
,
vector
<
KeyPoint
>&
queryP
oints
,
void
GenericDescriptorMatcher
::
match
(
const
Mat
&
queryIm
age
,
vector
<
KeyPoint
>&
queryKeyp
oints
,
vector
<
DMatch
>&
matches
,
const
vector
<
Mat
>&
masks
)
vector
<
DMatch
>&
matches
,
const
vector
<
Mat
>&
masks
)
{
{
vector
<
vector
<
DMatch
>
>
knnMatches
;
vector
<
vector
<
DMatch
>
>
knnMatches
;
knnMatch
(
queryIm
g
,
queryP
oints
,
knnMatches
,
1
,
masks
,
false
);
knnMatch
(
queryIm
age
,
queryKeyp
oints
,
knnMatches
,
1
,
masks
,
false
);
convertMatches
(
knnMatches
,
matches
);
convertMatches
(
knnMatches
,
matches
);
}
}
void
GenericDescriptorMatcher
::
knnMatch
(
const
Mat
&
queryIm
g
,
vector
<
KeyPoint
>&
queryP
oints
,
void
GenericDescriptorMatcher
::
knnMatch
(
const
Mat
&
queryIm
age
,
vector
<
KeyPoint
>&
queryKeyp
oints
,
vector
<
vector
<
DMatch
>
>&
matches
,
int
knn
,
vector
<
vector
<
DMatch
>
>&
matches
,
int
knn
,
const
vector
<
Mat
>&
masks
,
bool
compactResult
)
const
vector
<
Mat
>&
masks
,
bool
compactResult
)
{
{
train
();
train
();
knnMatchImpl
(
queryIm
g
,
queryP
oints
,
matches
,
knn
,
masks
,
compactResult
);
knnMatchImpl
(
queryIm
age
,
queryKeyp
oints
,
matches
,
knn
,
masks
,
compactResult
);
}
}
void
GenericDescriptorMatcher
::
radiusMatch
(
const
Mat
&
queryIm
g
,
vector
<
KeyPoint
>&
queryP
oints
,
void
GenericDescriptorMatcher
::
radiusMatch
(
const
Mat
&
queryIm
age
,
vector
<
KeyPoint
>&
queryKeyp
oints
,
vector
<
vector
<
DMatch
>
>&
matches
,
float
maxDistance
,
vector
<
vector
<
DMatch
>
>&
matches
,
float
maxDistance
,
const
vector
<
Mat
>&
masks
,
bool
compactResult
)
const
vector
<
Mat
>&
masks
,
bool
compactResult
)
{
{
train
();
train
();
radiusMatchImpl
(
queryIm
g
,
queryP
oints
,
matches
,
maxDistance
,
masks
,
compactResult
);
radiusMatchImpl
(
queryIm
age
,
queryKeyp
oints
,
matches
,
maxDistance
,
masks
,
compactResult
);
}
}
void
GenericDescriptorMatcher
::
read
(
const
FileNode
&
)
void
GenericDescriptorMatcher
::
read
(
const
FileNode
&
)
...
@@ -920,7 +916,7 @@ bool OneWayDescriptorMatcher::isMaskSupported()
...
@@ -920,7 +916,7 @@ bool OneWayDescriptorMatcher::isMaskSupported()
return
false
;
return
false
;
}
}
void
OneWayDescriptorMatcher
::
knnMatchImpl
(
const
Mat
&
queryIm
g
,
vector
<
KeyPoint
>&
queryP
oints
,
void
OneWayDescriptorMatcher
::
knnMatchImpl
(
const
Mat
&
queryIm
age
,
vector
<
KeyPoint
>&
queryKeyp
oints
,
vector
<
vector
<
DMatch
>
>&
matches
,
int
knn
,
vector
<
vector
<
DMatch
>
>&
matches
,
int
knn
,
const
vector
<
Mat
>&
/*masks*/
,
bool
/*compactResult*/
)
const
vector
<
Mat
>&
/*masks*/
,
bool
/*compactResult*/
)
{
{
...
@@ -928,30 +924,30 @@ void OneWayDescriptorMatcher::knnMatchImpl( const Mat& queryImg, vector<KeyPoint
...
@@ -928,30 +924,30 @@ void OneWayDescriptorMatcher::knnMatchImpl( const Mat& queryImg, vector<KeyPoint
CV_Assert
(
knn
==
1
);
// knn > 1 unsupported because of bug in OneWayDescriptorBase for this case
CV_Assert
(
knn
==
1
);
// knn > 1 unsupported because of bug in OneWayDescriptorBase for this case
matches
.
resize
(
query
P
oints
.
size
()
);
matches
.
resize
(
query
Keyp
oints
.
size
()
);
IplImage
_qimage
=
queryIm
g
;
IplImage
_qimage
=
queryIm
age
;
for
(
size_t
i
=
0
;
i
<
query
P
oints
.
size
();
i
++
)
for
(
size_t
i
=
0
;
i
<
query
Keyp
oints
.
size
();
i
++
)
{
{
int
descIdx
=
-
1
,
poseIdx
=
-
1
;
int
descIdx
=
-
1
,
poseIdx
=
-
1
;
float
distance
;
float
distance
;
base
->
FindDescriptor
(
&
_qimage
,
query
P
oints
[
i
].
pt
,
descIdx
,
poseIdx
,
distance
);
base
->
FindDescriptor
(
&
_qimage
,
query
Keyp
oints
[
i
].
pt
,
descIdx
,
poseIdx
,
distance
);
matches
[
i
].
push_back
(
DMatch
(
i
,
descIdx
,
distance
)
);
matches
[
i
].
push_back
(
DMatch
(
i
,
descIdx
,
distance
)
);
}
}
}
}
void
OneWayDescriptorMatcher
::
radiusMatchImpl
(
const
Mat
&
queryIm
g
,
vector
<
KeyPoint
>&
queryP
oints
,
void
OneWayDescriptorMatcher
::
radiusMatchImpl
(
const
Mat
&
queryIm
age
,
vector
<
KeyPoint
>&
queryKeyp
oints
,
vector
<
vector
<
DMatch
>
>&
matches
,
float
maxDistance
,
vector
<
vector
<
DMatch
>
>&
matches
,
float
maxDistance
,
const
vector
<
Mat
>&
/*masks*/
,
bool
/*compactResult*/
)
const
vector
<
Mat
>&
/*masks*/
,
bool
/*compactResult*/
)
{
{
train
();
train
();
matches
.
resize
(
query
P
oints
.
size
()
);
matches
.
resize
(
query
Keyp
oints
.
size
()
);
IplImage
_qimage
=
queryIm
g
;
IplImage
_qimage
=
queryIm
age
;
for
(
size_t
i
=
0
;
i
<
query
P
oints
.
size
();
i
++
)
for
(
size_t
i
=
0
;
i
<
query
Keyp
oints
.
size
();
i
++
)
{
{
int
descIdx
=
-
1
,
poseIdx
=
-
1
;
int
descIdx
=
-
1
,
poseIdx
=
-
1
;
float
distance
;
float
distance
;
base
->
FindDescriptor
(
&
_qimage
,
query
P
oints
[
i
].
pt
,
descIdx
,
poseIdx
,
distance
);
base
->
FindDescriptor
(
&
_qimage
,
query
Keyp
oints
[
i
].
pt
,
descIdx
,
poseIdx
,
distance
);
if
(
distance
<
maxDistance
)
if
(
distance
<
maxDistance
)
matches
[
i
].
push_back
(
DMatch
(
i
,
descIdx
,
distance
)
);
matches
[
i
].
push_back
(
DMatch
(
i
,
descIdx
,
distance
)
);
}
}
...
@@ -1064,18 +1060,18 @@ void FernDescriptorMatcher::calcBestProbAndMatchIdx( const Mat& image, const Poi
...
@@ -1064,18 +1060,18 @@ void FernDescriptorMatcher::calcBestProbAndMatchIdx( const Mat& image, const Poi
}
}
}
}
void
FernDescriptorMatcher
::
knnMatchImpl
(
const
Mat
&
queryIm
g
,
vector
<
KeyPoint
>&
queryP
oints
,
void
FernDescriptorMatcher
::
knnMatchImpl
(
const
Mat
&
queryIm
age
,
vector
<
KeyPoint
>&
queryKeyp
oints
,
vector
<
vector
<
DMatch
>
>&
matches
,
int
knn
,
vector
<
vector
<
DMatch
>
>&
matches
,
int
knn
,
const
vector
<
Mat
>&
/*masks*/
,
bool
/*compactResult*/
)
const
vector
<
Mat
>&
/*masks*/
,
bool
/*compactResult*/
)
{
{
train
();
train
();
matches
.
resize
(
query
P
oints
.
size
()
);
matches
.
resize
(
query
Keyp
oints
.
size
()
);
vector
<
float
>
signature
(
(
size_t
)
classifier
->
getClassCount
()
);
vector
<
float
>
signature
(
(
size_t
)
classifier
->
getClassCount
()
);
for
(
size_t
queryIdx
=
0
;
queryIdx
<
query
P
oints
.
size
();
queryIdx
++
)
for
(
size_t
queryIdx
=
0
;
queryIdx
<
query
Keyp
oints
.
size
();
queryIdx
++
)
{
{
(
*
classifier
)(
queryIm
g
,
queryP
oints
[
queryIdx
].
pt
,
signature
);
(
*
classifier
)(
queryIm
age
,
queryKeyp
oints
[
queryIdx
].
pt
,
signature
);
for
(
int
k
=
0
;
k
<
knn
;
k
++
)
for
(
int
k
=
0
;
k
<
knn
;
k
++
)
{
{
...
@@ -1099,17 +1095,17 @@ void FernDescriptorMatcher::knnMatchImpl( const Mat& queryImg, vector<KeyPoint>&
...
@@ -1099,17 +1095,17 @@ void FernDescriptorMatcher::knnMatchImpl( const Mat& queryImg, vector<KeyPoint>&
}
}
}
}
void
FernDescriptorMatcher
::
radiusMatchImpl
(
const
Mat
&
queryIm
g
,
vector
<
KeyPoint
>&
queryP
oints
,
void
FernDescriptorMatcher
::
radiusMatchImpl
(
const
Mat
&
queryIm
age
,
vector
<
KeyPoint
>&
queryKeyp
oints
,
vector
<
vector
<
DMatch
>
>&
matches
,
float
maxDistance
,
vector
<
vector
<
DMatch
>
>&
matches
,
float
maxDistance
,
const
vector
<
Mat
>&
/*masks*/
,
bool
/*compactResult*/
)
const
vector
<
Mat
>&
/*masks*/
,
bool
/*compactResult*/
)
{
{
train
();
train
();
matches
.
resize
(
query
P
oints
.
size
()
);
matches
.
resize
(
query
Keyp
oints
.
size
()
);
vector
<
float
>
signature
(
(
size_t
)
classifier
->
getClassCount
()
);
vector
<
float
>
signature
(
(
size_t
)
classifier
->
getClassCount
()
);
for
(
size_t
i
=
0
;
i
<
query
P
oints
.
size
();
i
++
)
for
(
size_t
i
=
0
;
i
<
query
Keyp
oints
.
size
();
i
++
)
{
{
(
*
classifier
)(
queryIm
g
,
queryP
oints
[
i
].
pt
,
signature
);
(
*
classifier
)(
queryIm
age
,
queryKeyp
oints
[
i
].
pt
,
signature
);
for
(
int
ci
=
0
;
ci
<
classifier
->
getClassCount
();
ci
++
)
for
(
int
ci
=
0
;
ci
<
classifier
->
getClassCount
();
ci
++
)
{
{
...
@@ -1206,21 +1202,21 @@ bool VectorDescriptorMatcher::isMaskSupported()
...
@@ -1206,21 +1202,21 @@ bool VectorDescriptorMatcher::isMaskSupported()
return
matcher
->
isMaskSupported
();
return
matcher
->
isMaskSupported
();
}
}
void
VectorDescriptorMatcher
::
knnMatchImpl
(
const
Mat
&
queryIm
g
,
vector
<
KeyPoint
>&
queryP
oints
,
void
VectorDescriptorMatcher
::
knnMatchImpl
(
const
Mat
&
queryIm
age
,
vector
<
KeyPoint
>&
queryKeyp
oints
,
vector
<
vector
<
DMatch
>
>&
matches
,
int
knn
,
vector
<
vector
<
DMatch
>
>&
matches
,
int
knn
,
const
vector
<
Mat
>&
masks
,
bool
compactResult
)
const
vector
<
Mat
>&
masks
,
bool
compactResult
)
{
{
Mat
queryDescriptors
;
Mat
queryDescriptors
;
extractor
->
compute
(
queryIm
g
,
queryP
oints
,
queryDescriptors
);
extractor
->
compute
(
queryIm
age
,
queryKeyp
oints
,
queryDescriptors
);
matcher
->
knnMatch
(
queryDescriptors
,
matches
,
knn
,
masks
,
compactResult
);
matcher
->
knnMatch
(
queryDescriptors
,
matches
,
knn
,
masks
,
compactResult
);
}
}
void
VectorDescriptorMatcher
::
radiusMatchImpl
(
const
Mat
&
queryIm
g
,
vector
<
KeyPoint
>&
queryP
oints
,
void
VectorDescriptorMatcher
::
radiusMatchImpl
(
const
Mat
&
queryIm
age
,
vector
<
KeyPoint
>&
queryKeyp
oints
,
vector
<
vector
<
DMatch
>
>&
matches
,
float
maxDistance
,
vector
<
vector
<
DMatch
>
>&
matches
,
float
maxDistance
,
const
vector
<
Mat
>&
masks
,
bool
compactResult
)
const
vector
<
Mat
>&
masks
,
bool
compactResult
)
{
{
Mat
queryDescriptors
;
Mat
queryDescriptors
;
extractor
->
compute
(
queryIm
g
,
queryP
oints
,
queryDescriptors
);
extractor
->
compute
(
queryIm
age
,
queryKeyp
oints
,
queryDescriptors
);
matcher
->
radiusMatch
(
queryDescriptors
,
matches
,
maxDistance
,
masks
,
compactResult
);
matcher
->
radiusMatch
(
queryDescriptors
,
matches
,
maxDistance
,
masks
,
compactResult
);
}
}
...
@@ -1245,7 +1241,8 @@ Ptr<GenericDescriptorMatcher> VectorDescriptorMatcher::clone( bool emptyTrainDat
...
@@ -1245,7 +1241,8 @@ Ptr<GenericDescriptorMatcher> VectorDescriptorMatcher::clone( bool emptyTrainDat
/*
/*
* Factory function for GenericDescriptorMatch creating
* Factory function for GenericDescriptorMatch creating
*/
*/
Ptr
<
GenericDescriptorMatcher
>
createGenericDescriptorMatcher
(
const
string
&
genericDescritptorMatcherType
,
const
string
&
paramsFilename
)
Ptr
<
GenericDescriptorMatcher
>
createGenericDescriptorMatcher
(
const
string
&
genericDescritptorMatcherType
,
const
string
&
paramsFilename
)
{
{
Ptr
<
GenericDescriptorMatcher
>
descriptorMatcher
;
Ptr
<
GenericDescriptorMatcher
>
descriptorMatcher
;
if
(
!
genericDescritptorMatcherType
.
compare
(
"ONEWAY"
)
)
if
(
!
genericDescritptorMatcherType
.
compare
(
"ONEWAY"
)
)
...
@@ -1256,12 +1253,8 @@ Ptr<GenericDescriptorMatcher> createGenericDescriptorMatcher( const string& gene
...
@@ -1256,12 +1253,8 @@ Ptr<GenericDescriptorMatcher> createGenericDescriptorMatcher( const string& gene
{
{
descriptorMatcher
=
new
FernDescriptorMatcher
();
descriptorMatcher
=
new
FernDescriptorMatcher
();
}
}
else
if
(
!
genericDescritptorMatcherType
.
compare
(
"CALONDER"
)
)
{
//descriptorMatch = new CalonderDescriptorMatch ();
}
if
(
!
paramsFilename
.
empty
()
&&
descriptorMatcher
!=
0
)
if
(
!
paramsFilename
.
empty
()
&&
!
descriptorMatcher
.
empty
()
)
{
{
FileStorage
fs
=
FileStorage
(
paramsFilename
,
FileStorage
::
READ
);
FileStorage
fs
=
FileStorage
(
paramsFilename
,
FileStorage
::
READ
);
if
(
fs
.
isOpened
()
)
if
(
fs
.
isOpened
()
)
...
...
samples/cpp/matching_to_many_images.cpp
View file @
c6e43c38
...
@@ -69,7 +69,7 @@ bool createDetectorDescriptorMatcher( const string& detectorType, const string&
...
@@ -69,7 +69,7 @@ bool createDetectorDescriptorMatcher( const string& detectorType, const string&
bool
isCreated
=
!
(
featureDetector
.
empty
()
||
descriptorExtractor
.
empty
()
||
descriptorMatcher
.
empty
()
);
bool
isCreated
=
!
(
featureDetector
.
empty
()
||
descriptorExtractor
.
empty
()
||
descriptorMatcher
.
empty
()
);
if
(
!
isCreated
)
if
(
!
isCreated
)
cout
<<
"Can not create feature detector or descriptor ex
s
tractor or descriptor matcher of given types."
<<
endl
<<
">"
<<
endl
;
cout
<<
"Can not create feature detector or descriptor extractor or descriptor matcher of given types."
<<
endl
<<
">"
<<
endl
;
return
isCreated
;
return
isCreated
;
}
}
...
...
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