您的位置:首页 > 运维架构

【图像特征提取8】OpenCv中SURF源码的分析一

2017-03-17 22:44 459 查看
/********************************************************************************************************
文件说明:
OpenCv中SURF源码的分析
开发环境:
Win7 + OpenCv2.4.8 + VS2012
时间地点:
陕西师范大学 2017.3.17
作    者:
九 月
*********************************************************************************************************/
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/nonfree/features2d.hpp>
using namespace cv;
using namespace std;

/********************************************************************************************************
函数描述:
OpenCv中,和SURF类相关的源码分析
1)在OpenCv中和SURF算法有关的源代码部分,常常涉及到的类有三个类,分别如下所示:
1)SURF
2)SurfFeatureDetector
3)SurfDescriptorExtractor
我们可以通过转到定义,在opencv2/nonfree/features2d.hpp头文件中,发现以下的代码,通过下面的代码,我们
可以知道cv::SURF、cv::SurfFeatureDetector、cv::SurfDescriptorExtractor这三个类等价。然后,在这两行代码的
上方,我们就可以看到定义SURF类的全部类声明代码,这也是有关SURF类最关键的代码部分,具体的代码如下所示:
*********************************************************************************************************/

typedef SURF SurfFeatureDetector;
typedef SURF SurfDescriptorExtractor;

//【1】SURF类的定义

class CV_EXPORTS_W SURF : public Feature2D
{
public:
//【1】SURF类的默认构造函数
CV_WRAP SURF();
//【2】SURF类的带参数的构造函数
explicit CV_WRAP SURF(double hessianThreshold,                     //【1】Hessian判别式的阈值
int    nOctaves=4,                           //【2】SURF算法中,默认的金字塔层数Octave
int    nOctaveLayers=2,                      //【3】每层的图片数
bool   extended=true,
bool upright=false);

//【3】返回SURF特征向量(特征描述子)的尺寸,是64维还是128维
CV_WRAP int descriptorSize() const;
//【4】返回SURF特征描述子(或者说特征向量)的类型
CV_WRAP int descriptorType() const;
//【5】在SURF算法中使用快速Hessian检测器检测出图像的关键点(特征点)
void operator()(InputArray img,                                      //【1】输入的、待检测的图像
InputArray mask,                                     //【2】图像的掩膜
CV_OUT vector<KeyPoint>& keypoints) const;
//【6】找到关键点,并且计算SUFR特征点的特征描述子
void operator()(InputArray img,
InputArray mask,
CV_OUT vector<KeyPoint>& keypoints,
OutputArray descriptors,
bool useProvidedKeypoints=false) const;
//【7】输出算法的相关信息
AlgorithmInfo* info() const;

CV_PROP_RW double hessianThreshold;                                   //【1】设置Hessian矩阵判别式的阈值
CV_PROP_RW int    nOctaves;                                            //【2】金字塔图像的层数Octave
CV_PROP_RW int    nOctaveLayers;                                       //【3】金字塔图像每层具有的图片数Layers
CV_PROP_RW bool   extended;
CV_PROP_RW bool   upright;

protected:

void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
void computeImpl( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors ) const;
};
/********************************************************************************************************
模块描述:
除了上面所讲的代码之外,我们还可以看到SURF类是公有继承自Feature2D类;我们在以后的编程过程中,除了
使用SURF源代码中出现的成员函数之外,我们通常还会经常使用两个函数,这两个函数如下所示:
1)detect()
2) computer()
*********************************************************************************************************/
void detect( const Mat& image, CV_OUT vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
void detect( const vector<Mat>& images, vector<vector<KeyPoint> >& keypoints, const vector<Mat>& masks=vector<Mat>() ) const;
/********************************************************************************************************
模块描述:
上面的detect是两个重载的函数,这两个函数的作用是,检测SURF算法中的关键点,具体的分析如下所示:
*********************************************************************************************************/
void detect( const Mat& image,                     //【1】输入的待检测的图像
CV_OUT vector<KeyPoint>& keypoints,     //【2】将检测出来的关键点存储数组keypoints
const Mat& mask=Mat() ) const;
void detect( const vector<Mat>& images,            //【1】要进行关键点检测的图像集合
vector<vector<KeyPoint> >& keypoints,   //【2】存储检测出来的关键点的数组
const vector<Mat>& masks=vector<Mat>() ) const;
/********************************************************************************************************
模块描述:
那么,在SURF算法中,用来检测SURF算法中关键点的函数是什么呢?具体的函数如下所示:
*********************************************************************************************************/
void detectImpl( const Mat& image,                 //【1】输入待检测关键点的图像
vector<KeyPoint>& keypoints,        //【2】保存SURF算法中关键点检测函数检测出来的关键点
const Mat& mask=Mat() ) const;
/********************************************************************************************************
模块描述:
我们都知道,SURF算法中的关键点检测出来之后,我们需要根据SURF算法检测出来的关键点计算关键点对应的SURF特
征描述子(或者说SURF算法的特征向量),那么计算SURF算法特征向量的函数又是什么呢?具体的代码如下所示:
就是下面这两个函数,这两个函数就是根据关键点计算特征特征向量的函数。
*********************************************************************************************************/
void compute( const Mat& image,                             //【1】输入待计算关键点特征向量的图像
CV_OUT CV_IN_OUT vector<KeyPoint>& keypoints,   //【2】输入上一步利用detect()函数检测出来的关键点
CV_OUT Mat& descriptors ) const;                //【3】存储利用这个函数计算出来的特征点描述子或者说特征向量
void compute( const vector<Mat>& images, vector<vector<KeyPoint> >& keypoints, vector<Mat>& descriptors ) const;
/********************************************************************************************************
模块描述:
下面就是SURF算法中,根据关键点计算特征向量的函数,具体函数如下所示:
*********************************************************************************************************/
void computeImpl( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors ) const;
/********************************************************************************************************
模块描述:
绘制关键点的函数:drawKeypoints()
*********************************************************************************************************/
void drawKeypoints( const Mat& image,                       //【1】输入图像
const vector<KeyPoint>& keypoints,      //【2】输入关键点的坐标
CV_OUT Mat& outImage,                     //【3】输出图像,其内容取决于第五个参数
const Scalar& color=Scalar::all(-1),    //【4】关键点的颜色值
int flags=DrawMatchesFlags::DEFAULT );   //【5】绘制关键点的标识符

class CV_EXPORTS_W_SIMPLE KeyPoint
{
public:
CV_PROP_RW Point2f pt;                                 //【1】关键点的坐标
CV_PROP_RW float size;                                 //【2】关键点邻域直径
CV_PROP_RW float angle;                                //【3】特征点的方向
CV_PROP_RW float response;                             //【4】特征点的响应值
CV_PROP_RW int octave;                                  //【5】特征点所在的层Octave
CV_PROP_RW int class_id;                                //【6】用于聚类的id
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: