OpenCV学习之旅9——特征检测与匹配(1)

1. 常用的特征检测常用方法

  1. FAST——FastFeatureDetector
  2. STAR——StarFeatureDetector
  3. SIFT——SIFT(nonfree module)
  4. SURF——SURF(nonfree module)
  5. ORB——ORB
  6. MSER——MSER
  7. GFTT——GoodFeatureToTrackDetector
  8. HARRIS——GoodFeatureToTrackDetector(配合HarrisDetector操作)
  9. Dense——DenseFeatureDetector
  10. SimpleBlob——SimpleBlobDetector

2. SURF特征点检测

2.1 SURF算法概述

SURF英文全称为SpeedUp Robust Features。SURF是SIFT算法的加速版 。SURF可以用于计算机视觉的物体识别以及3D重构中。

2.2 SURF算法原理

① 构建Hessian矩阵构建高斯金字塔尺度空间
SIFT采用的是DOG图像(Difference of Gaussian),而SURF采用的是Hessian矩阵近似值图像。Hessian矩阵是SURF算法的核心。
海森矩阵是一个自变量为实值函数二阶偏导数组成的方块矩阵。所以图像中某个像素点的Hessian矩阵为

H(f(x,y))=2fx22fxy2fxy2fy2 H ( f ( x , y ) ) = [ ∂ 2 f ∂ x 2 ∂ 2 f ∂ x ∂ y ∂ 2 f ∂ x ∂ y ∂ 2 f ∂ y 2 ]

且每一个像素点都可以求出一个Hessian矩阵。
H矩阵的判别式为:
det(H)=2f2fx2y2(2fxy)2 d e t ( H ) = ∂ 2 f ∂ 2 f ∂ x 2 ∂ y 2 − ( ∂ 2 f ∂ x ∂ y ) 2

根据判别式的正负情况可以判断该点是不是极值点。
求Hessian矩阵时要先进行高斯滤波,然后再求二阶导数。
经过上述步骤得到一张近似Hessian行列式图。
②利用非极大值抑制初步确定特征点
将经过Hessian矩阵处理的每个像素点与三位邻域的26个点进行比较,如果它是最大值或最小值,则保留,当做初步特征点。
这里写图片描述
③精确定位极值点
采用三维线性插值法得到亚像素级特征点,同时将小于一定阈值的点去除,得到几个特征最强的点。
④选取特征点的主方向
⑤构造SURF特征点描述算子

2.3 SURF类在OpenCV代码分析

在OpenCV中SURF类、SurfFeatureDetector类、SurfDescriptorExtractor类等价。

2.3.1 drawKeypoints()函数

void drawKeypoints( const Mat& image, const vector<KeyPoint>& keypoints, CV_OUT Mat& outImage,const Scalar& color=Scalar::all(-1), int flags=DrawMatchesFlags::DEFAULT );

第二个参数:const vector< KeyPoint >& 类型的keypoints,根据图像得到的特征点;
第三个参数:输出图像,其形式取决于第五个参数;
第四个参数:关键点的颜色;
第五个参数:int 类型的 flags,默认为DEFAULT,表示使用创建的的输出图像绘制匹配对和特征点;当为DRAW_ OVER _OUTIMG时,不创建输出图像矩阵而是在输出图像上绘制匹配对……

2.3.2 KeyPoint类

KeyPoint类用于表示特征点。

class KeyPoint
{
    Point2f pt;  //坐标
    float size;  //特征点邻域直径;
    float angle; //特征点方向,值为0-360
    float response;
    int octave;  //特征点所在的图像金字塔的组
    int class_id;//用于聚类的id
}

2.3.3 程序实例

#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/nonfree/nonfree.hpp"
#include <iostream>
using namespace cv;

//-----------------------------------【main( )函数】--------------------------------------------
//   描述:控制台应用程序的入口函数,我们的程序从这里开始执行
//-----------------------------------------------------------------------------------------------
int main( int argc, char** argv )
{
    //【0】改变console字体颜色    
    system("color 2F");    

    //【1】载入源图片并显示
    Mat srcImage1 = imread("1.jpg", 1 );
    Mat srcImage2 = imread("2.jpg", 1 );
    if( !srcImage1.data || !srcImage2.data )//检测是否读取成功
    { printf("读取图片错误,请确定目录下是否有imread函数指定名称的图片存在~! \n"); return false; } 
    imshow("原始图1",srcImage1);
    imshow("原始图2",srcImage2);

    //【2】定义需要用到的变量和类
    int minHessian = 400;//定义SURF中的hessian阈值特征点检测算子
    SurfFeatureDetector detector( minHessian );//定义一个SurfFeatureDetector(SURF) 特征检测类对象
    std::vector<KeyPoint> keypoints_1, keypoints_2;//vector模板类是能够存放任意类型的动态数组,能够增加和压缩数据

    //【3】调用detect函数检测出SURF特征关键点,保存在vector容器中
    detector.detect( srcImage1, keypoints_1 );
    detector.detect( srcImage2, keypoints_2 );

    //【4】绘制特征关键点.
    Mat img_keypoints_1; Mat img_keypoints_2;
    drawKeypoints( srcImage1, keypoints_1, img_keypoints_1, Scalar::all(-1), DrawMatchesFlags::DEFAULT );
    drawKeypoints( srcImage2, keypoints_2, img_keypoints_2, Scalar::all(-1), DrawMatchesFlags::DEFAULT );

    //【5】显示效果图
    imshow("特征点检测效果图1", img_keypoints_1 );
    imshow("特征点检测效果图2", img_keypoints_2 );

    waitKey(0);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值