特征描述子匹配公用接口

OpenCV封装了一些特征描述子匹配算法,使得用户能够解决该问题时候方便使用各种算法。这章用来计算的描述子匹配被表达成一个高维空间的向量 vector.所有实现 vector 特征描述子子提取的部分继承了 DescriptorExtractor 接口.

DMatch

class DMatch

用于匹配特征关键点的特征描述子的类:查询特征描述子索引, 特征描述子索引, 训练图像索引, 以及不同特征描述子之间的距离.

struct DMatch
{
    DMatch() : queryIdx(-1), trainIdx(-1), imgIdx(-1),
               distance(std::numeric_limits<float>::max()) {}
    DMatch( int _queryIdx, int _trainIdx, float _distance ) :
            queryIdx(_queryIdx), trainIdx(_trainIdx), imgIdx(-1),
            distance(_distance) {}
    DMatch( int _queryIdx, int _trainIdx, int _imgIdx, float _distance ) :
            queryIdx(_queryIdx), trainIdx(_trainIdx), imgIdx(_imgIdx),
            distance(_distance) {}

    int queryIdx; // query descriptor index
    int trainIdx; // train descriptor index
    int imgIdx;   // train image index

    float distance;

    // less is better
    bool operator<( const DMatch &m ) const;
};

DescriptorMatcher

class DescriptorMatcher

用于特征关键点描述子匹配的抽象基类. 有两类匹配任务:匹配两个图像之间的特征描述子,或者匹配一个图像与另外一个图像集的特征描述子.

class DescriptorMatcher
{
public:
    virtual ~DescriptorMatcher();

    virtual void add( const vector<Mat>& descriptors );

    const vector<Mat>& getTrainDescriptors() const;
    virtual void clear();
    bool empty() const;
    virtual bool isMaskSupported() const = 0;

    virtual void train();

    /*
     * Group of methods to match descriptors from an image pair.
     */
    void match( const Mat& queryDescriptors, const Mat& trainDescriptors,
                vector<DMatch>& matches, const Mat& mask=Mat() ) const;
    void knnMatch( const Mat& queryDescriptors, const Mat& trainDescriptors,
                   vector<vector<DMatch> >& matches, int k,
                   const Mat& mask=Mat(), bool compactResult=false ) const;
    void radiusMatch( const Mat& queryDescriptors, const Mat& trainDescriptors,
                      vector<vector<DMatch> >& matches, float maxDistance,
                      const Mat& mask=Mat(), bool compactResult=false ) const;
    /*
     * Group of methods to match descriptors from one image to an image set.
     */
    void match( const Mat& queryDescriptors, vector<DMatch>& matches,
                const vector<Mat>& masks=vector<Mat>() );
    void knnMatch( const Mat& queryDescriptors, vector<vector<DMatch> >& matches,
                   int k, const vector<Mat>& masks=vector<Mat>(),
                   bool compactResult=false );
    void radiusMatch( const Mat& queryDescriptors, vector<vector<DMatch> >& matches,
                      float maxDistance, const vector<Mat>& masks=vector<Mat>(),
                      bool compactResult=false );

    virtual void read( const FileNode& );
    virtual void write( FileStorage& ) const;

    virtual Ptr<DescriptorMatcher> clone( bool emptyTrainData=false ) const = 0;

    static Ptr<DescriptorMatcher> create( const string& descriptorMatcherType );

protected:
    vector<Mat> trainDescCollection;
    ...
};

DescriptorMatcher::add

增加特征描述子用于特征描述子集训练. 如果这个集 trainDescCollectionis 是非空的, 新特征描述子增加到现有的待训练的特征描述子集中.

C++: void DescriptorMatcher::add(const vector<Mat>& descriptors)
Parameters:
  • descriptors – Descriptors to add. Each descriptors[i] is a set of descriptors from the same train image.

DescriptorMatcher::getTrainDescriptors

对于特征描述子训练集``trainDescCollection`` 返回一个值.

C++: const vector<Mat>& DescriptorMatcher::getTrainDescriptors() const

DescriptorMatcher::clear

清空特征描述子训练集.

C++: void DescriptorMatcher::clear()

DescriptorMatcher::empty

返回真,如果特征描述子匹配中没有训练的特征描述子.

C++: bool DescriptorMatcher::empty() const

DescriptorMatcher::isMaskSupported

返回真,如果特征描述子匹配不支持 masking permissible matches.

C++: bool DescriptorMatcher::isMaskSupported()

DescriptorMatcher::train

训练一个特征描述子匹配

C++: void DescriptorMatcher::train()

Trains a descriptor matcher (for example, the flann index). In all methods to match, the method train() is run every time before matching. Some descriptor matchers (for example, BruteForceMatcher) have an empty implementation of this method. Other matchers really train their inner structures (for example, FlannBasedMatcher trains flann::Index ).

DescriptorMatcher::match

给定查询集合中的每个特征描述子,寻找 最佳匹配.

C++: void DescriptorMatcher::match(const Mat& queryDescriptors, const Mat& trainDescriptors, vector<DMatch>& matches, const Mat& mask=Mat() ) const
C++: void DescriptorMatcher::match(const Mat& queryDescriptors, vector<DMatch>& matches, const vector<Mat>& masks=vector<Mat>() )
Parameters:
  • queryDescriptors – 特征描述子查询集.
  • trainDescriptors – 待训练的特征描述子集. 这个集没被加载到类的对象中.
  • matches – Matches. matches 尺寸小雨超汛特征描述子的数量.
  • mask – 特定的在输入查询和训练特征描述子集之间的Mask permissible匹配.
  • masks – masks集. 每个 masks[i] 特定标记出了在输入查询特征描述子和存储的从第i个图像中提取的特征描述子集``trainDescCollection[i]``.

In the first variant of this method, the train descriptors are passed as an input argument. In the second variant of the method, train descriptors collection that was set by DescriptorMatcher::add is used. Optional mask (or masks) can be passed to specify which query and training descriptors can be matched. Namely, queryDescriptors[i] can be matched with trainDescriptors[j] only if mask.at<uchar>(i,j) is non-zero.

DescriptorMatcher::knnMatch

给定查询集合中的每个特征描述子,寻找 k个最佳匹配.

C++: void DescriptorMatcher::knnMatch(const Mat& queryDescriptors, const Mat& trainDescriptors, vector<vector<DMatch>>& matches, int k, const Mat& mask=Mat(), bool compactResult=false ) const
C++: void DescriptorMatcher::knnMatch(const Mat& queryDescriptors, vector<vector<DMatch>>& matches, int k, const vector<Mat>& masks=vector<Mat>(), bool compactResult=false )
Parameters:
  • queryDescriptors – Query set of descriptors.
  • trainDescriptors – Train set of descriptors. This set is not added to the train descriptors collection stored in the class object.
  • mask – Mask specifying permissible matches between an input query and train matrices of descriptors.
  • masks – Set of masks. Each masks[i] specifies permissible matches between the input query descriptors and stored train descriptors from the i-th image trainDescCollection[i].
  • matches – Matches. Each matches[i] is k or less matches for the same query descriptor.
  • k – Count of best matches found per each query descriptor or less if a query descriptor has less than k possible matches in total.
  • compactResult – Parameter used when the mask (or masks) is not empty. If compactResult is false, the matches vector has the same size as queryDescriptors rows. If compactResult is true, the matches vector does not contain matches for fully masked-out query descriptors.

These extended variants of DescriptorMatcher::match() methods find several best matches for each query descriptor. The matches are returned in the distance increasing order. See DescriptorMatcher::match() for the details about query and train descriptors.

DescriptorMatcher::radiusMatch

对于每一个查询特征描述子, 在特定距离范围内寻找特征描述子.

C++: void DescriptorMatcher::radiusMatch(const Mat& queryDescriptors, const Mat& trainDescriptors, vector<vector<DMatch>>& matches, float maxDistance, const Mat& mask=Mat(), bool compactResult=false ) const
C++: void DescriptorMatcher::radiusMatch(const Mat& queryDescriptors, vector<vector<DMatch>>& matches, float maxDistance, const vector<Mat>& masks=vector<Mat>(), bool compactResult=false )
Parameters:
  • queryDescriptors – Query set of descriptors.
  • trainDescriptors – Train set of descriptors. This set is not added to the train descriptors collection stored in the class object.
  • mask – Mask specifying permissible matches between an input query and train matrices of descriptors.
  • masks – Set of masks. Each masks[i] specifies permissible matches between the input query descriptors and stored train descriptors from the i-th image trainDescCollection[i].
  • matches – Found matches.
  • compactResult – Parameter used when the mask (or masks) is not empty. If compactResult is false, the matches vector has the same size as queryDescriptors rows. If compactResult is true, the matches vector does not contain matches for fully masked-out query descriptors.
  • maxDistance – Threshold for the distance between matched descriptors.

For each query descriptor, the methods find such training descriptors that the distance between the query descriptor and the training descriptor is equal or smaller than maxDistance. Found matches are returned in the distance increasing order.

DescriptorMatcher::clone

拷贝匹配.

C++: Ptr<DescriptorMatcher> DescriptorMatcher::clone(bool emptyTrainData) const
Parameters:
  • emptyTrainData – If emptyTrainData is false, the method creates a deep copy of the object, that is, copies both parameters and train data. If emptyTrainData is true, the method creates an object copy with the current parameters but with empty train data.

DescriptorMatcher::create

对于给定参数,创建特征描述子匹配(使用默认的构造函数).

C++: Ptr<DescriptorMatcher> DescriptorMatcher::create(const string& descriptorMatcherType)
Parameters:
  • descriptorMatcherType

    Descriptor matcher type. Now the following matcher types are supported:

    • BruteForce (it uses L2 )
    • BruteForce-L1
    • BruteForce-Hamming
    • BruteForce-HammingLUT
    • FlannBased

BruteForceMatcher

class BruteForceMatcher

暴力搜索特征点匹配. 对于第一集合中的特征描述子, 这个匹配寻找了在第二个集合中最近的特征描述子. 这种特征描述子匹配支持 masking permissible特征描述子集合匹配.

template<class Distance>
class BruteForceMatcher : public DescriptorMatcher
{
public:
    BruteForceMatcher( Distance d = Distance() );
    virtual ~BruteForceMatcher();

    virtual bool isMaskSupported() const;
    virtual Ptr<DescriptorMatcher> clone( bool emptyTrainData=false ) const;
protected:
    ...
}

For efficiency, BruteForceMatcher is used as a template parameterized with the distance type. For float descriptors, L2<float> is a common choice. The following distances are supported:

template<typename T>
struct Accumulator
{
    typedef T Type;
};

template<> struct Accumulator<unsigned char>  { typedef unsigned int Type; };
template<> struct Accumulator<unsigned short> { typedef unsigned int Type; };
template<> struct Accumulator<char>   { typedef int Type; };
template<> struct Accumulator<short>  { typedef int Type; };

/*
 * Euclidean distance functor
 */
template<class T>
struct L2
{
    typedef T ValueType;
    typedef typename Accumulator<T>::Type ResultType;

    ResultType operator()( const T* a, const T* b, int size ) const;
};

/*
 * Squared Euclidean distance functor
 */
template<class T>
struct SL2
{
    typedef T ValueType;
    typedef typename Accumulator<T>::Type ResultType;

    ResultType operator()( const T* a, const T* b, int size ) const;
};
// Note: in case of SL2 distance a parameter maxDistance in the method DescriptorMatcher::radiusMatch
// is a squared maximum distance in L2.

/*
 * Manhattan distance (city block distance) functor
 */
template<class T>
struct CV_EXPORTS L1
{
    typedef T ValueType;
    typedef typename Accumulator<T>::Type ResultType;

    ResultType operator()( const T* a, const T* b, int size ) const;
};

/*
 * Hamming 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;
};

FlannBasedMatcher

class FlannBasedMatcher

基于Flann的特征描述子匹配. 这个匹配通过 flann::Index_ 在 特征描述子集上训练以及调用最近邻算法寻找最佳的匹配. 因此, 在大量训练样本数据集上,这个匹配会比暴力寻找快. 因为 flann::Index 的原因,``FlannBasedMatcher`` 不支持masking permissible特征描述子集合匹配.

class FlannBasedMatcher : public DescriptorMatcher
{
public:
    FlannBasedMatcher(
      const Ptr<flann::IndexParams>& indexParams=new flann::KDTreeIndexParams(),
      const Ptr<flann::SearchParams>& searchParams=new flann::SearchParams() );

    virtual void add( const vector<Mat>& descriptors );
    virtual void clear();

    virtual void train();
    virtual bool isMaskSupported() const;

    virtual Ptr<DescriptorMatcher> clone( bool emptyTrainData=false ) const;
protected:
    ...
};