OpenCV2学习笔记(十二):SURF与SIFT算法

当尝试在不同图像之间进行特征匹配时,通常会遇到图像的大小、方向等参数发生改变的问题,简而言之,就是尺度变化的问题。每幅图像在拍摄时与目标物体的距离是不同的,因此要识别的目标物体在图像中自然会存在不同的尺寸。

因此,计算机视觉中引入尺度不变的特征,主要的思想是每个检测到的特征点都伴随对应的尺度因子。著名的尺度不变特征检测器SIFT(scale invariant feature transform),具有尺度,旋转,仿射,视角,光照不变性。而加速鲁棒特性特征SURF(Speeded Up Robust Features)算法是SIFT的高效变种。

关于SIFT和SURF的特征介绍,已经有很多的blog对其进行简介了,见参考的blog。由于还没有将2004年那篇原文精细看完,这里只是提供在OpenCV中如何实现这两种算法的特征检测。这里使用的开发平台是Qt5.3.2+OpenCV2.4.9。SURF、SIFT特征在OpenCV中的实现均使用了cv::FeatureDetector接口。在这里,特征点的计算基于浮点核,因此这两种算法相比其他算法在空间和尺度检测上更加精确,但相对耗时。

至于理论部分有待更新。

一、SIFT特征

直接在Qt中创建一个控制台项目,在main函数中添加:

#include <QCoreApplication>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/nonfree/nonfree.hpp>

#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // 读入图像
    cv::Mat image= cv::imread("c:/018.jpg",0);
    cv::namedWindow("Original Image");
    cv::imshow("Original Image", image);
    // 特征点的向量
    std::vector<cv::KeyPoint>keypoints;
        // 构造SIFT特征检测器
    cv::SiftFeatureDetector sift(
        0.03,  // 特征的阈值
        10.);  // 用于降低

    // 检测SIFT特征值
    sift.detect(image,keypoints);

    cv::drawKeypoints(image, // 原始图像
                      keypoints, // 特征点的向量
                      featureImage, // 生成图像
                      cv::Scalar(255,255,255), // 特征点的颜色
                      cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS); // 标志位

    cv::namedWindow("SIFT Features");
    cv::imshow("SIFT Features",featureImage);

    return a.exec();
}

效果如下,在函数cv::drawKeypoints中我们使用cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS作为标志位,这样唉使用DRAW_RICH_KEYPOINTS之后每个关键点上圆圈的尺寸与特征的尺度成正比:

二、SURF特征

#include <QCoreApplication>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/nonfree/nonfree.hpp>

#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // 读入图像
    cv::Mat image= cv::imread("c:/018.jpg",0);
    cv::namedWindow("Original Image");
    cv::imshow("Original Image", image);
    // 特征点的向量
    std::vector<cv::KeyPoint>keypoints;

    // 构造SURF特征检测器
    cv::SurfFeatureDetector surf(2500);
    // 检测SURF特征
    surf.detect(image,keypoints);

    cv::Mat featureImage;
    cv::drawKeypoints(image, // 原始图像
                      keypoints, // 特征点的向量
                      featureImage, // 生成图像
                      cv::Scalar(255,255,255), // 特征点的颜色
                      cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS); // 标志位

    cv::namedWindow("SURF Features");
    cv::imshow("SURF Features",featureImage);

    return a.exec();
}

效果:

相比SIFT特征,SURF牺牲了一定的精度换取了计算效率的提高。关于这两种算法的理论部分有待进一步的探讨和更新…

参考blog:

http://blog.csdn.net/xiaowei_cqu/article/details/8069548

http://www.cnblogs.com/tornadomeet/archive/2012/08/16/2643168.html

时间: 2024-12-07 19:39:41

OpenCV2学习笔记(十二):SURF与SIFT算法的相关文章

Swift学习笔记十二:下标脚本(subscript)

下标脚本就是对一个东西通过索引,快速取值的一种语法,例如数组的a[0].这就是一个下标脚本.通过索引0来快速取值.在Swift中,我们可以对类(Class).结构体(structure)和枚举(enumeration)中自己定义下标脚本的语法 一.常规定义 class Student{ var scores:Int[] = Array(count:5,repeatedValue:0) subscript(index:Int) -> Int{ get{ return scores[index];

虚拟机VMWare学习笔记十二 - 将物理机抓取成虚拟机

1. 安装VMware vCenter Converter Standalone Client 运行虚拟机,File -- Virtualize a Physical Machine 这时如果电脑中没有VMware vCenter Converter Standalone Client ,则会进行安装. 安装过程 之后图标会出现在桌面上,双击运行 选择连接到本地服务器,登陆 点击转换计算机 这个,可以将本地计算机抓取成虚拟机,也可以将其他可以访问的计算机(需知道管理员用户名及密码)抓取成虚拟机.

《Hibernate学习笔记十二》学生、课程、分数关系的设计与实现

<Hibernate学习笔记十二>学生.课程.分数关系的设计与实现 这个马士兵老师的Hibernate视频学习的一个题目,这里面要用到多对多.多对一的关联关系以及联合主键,因此觉得挺好的,自己写篇博文来记录下. 先考虑数据库表 1.学生表:为简单起见,只考虑了学生id和学生姓名,其中id为主键 2.课程表:为简单起见,只考虑了课程id和课程名称,其中id为主键 3.分数表 分数表有两种解决方案 3.1 第一种为:使用联合主键:student_id 和 course_id 3.2 第二种:不使用

laravel3学习笔记(十二)

原作者博客:ieqi.net ==================================================================================================== 请求反射 HTTP 协议本身是无状态性的,但是在应用中处理各种业务逻辑时我们必须要有状态的把控,这样,折中的办法就是将状态进行标记然后嵌入到 HTTP 协议的请求中,然后应用根据这些标记来进行状态的串联以及处理.所以我们就要对请求进行反射处理以获取请求信息, Lara

OpenCV2学习笔记(二十二):ORB特征提取

ORB(ORiented Brief)特征提取算法,其前身Brief,是由EPFL的Calonder在ECCV2010上提出了一种可以快速计算且表达方式为二进制编码的描述子,主要思路就是在特征点附近随机选取若干点对,将这些点对的灰度值的大小,组合成一个二进制串,并将这个二进制串作为该特征点的特征描述子.BRIEF最大的优点在于速度快,然而其缺点也相当明显,主要有以下几方面: 不具有旋转不变性: 不具有尺度不变性: 对抗噪声性能差. ORB就是试图解决上述缺点中的1和3,即具有旋转不变性的同时具有

java jvm学习笔记十二(访问控制器的栈校验机制)

欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 本节源码:http://download.csdn.net/detail/yfqnihao/4863854 这一节,我们会简单的描述一下jvm访问控制器的栈校验机制. 这节课,我们还是以实践为主,什么是栈校验机制,讲一百遍不如你自己实际的代码一下然后验证一下,下面我们下把环境搭起来. 第一步,配置系统环境.(copy吧,少年) path=%JAVA_HOME%/bin JAVA_HOME=C:/Java/jdk1.6

OpenCV2学习笔记(二十一):GPU模块小记

接触一下OpenCV里一个之前没有接触的模块:GPU.这里只是根据教程和大家简单交流一下,欢迎大家批评指正. 注:在使用GPU模块之前,需要确认在使用CMake编译OpenCV时,勾选了选项WITH_CUDA和WITH_TBB使其生效生效. 若以上配置已经完成,在使用GPU模块的函数之前,还做一下检查:调用函数gpu::getCudaEnabledDeviceCount,如果你在使用的OpenCV模块编译时不支持GPU,这个函数返回值为0:否则返回值为已安装的CUDA设备的数量. OpenCV的

OpenCV2学习笔记(二):图像的直方图

直方图(Histogram)又称质量分布图.是一种统计报告图,由一系列高度不等的纵向条纹或线段表示数据分布的情况.一般用横轴表示数据类型,纵轴表示分布情况.众所周知,一幅图像是由不同颜色值的像素组成,因此像素值在图像中的分布情况是这幅图像的一个重要特征,因此直方图广泛应用在数字图像处理中. 拍照是现实生活中必不可少的一部分,由于环境亮度.图像拍摄过程中透视光圈设置错误等影响,经常会拍出一些"过暗"的照片,此时美图.PS等美化工具可以派上用场.但是这些工具的算法通常都是不公开的,鉴于研究

OC学习笔记十二 多态

一.多态概念 多态的前提,必须存在继承关系,在代码中的表现形式就是父类类型保存子类类型,即父类的指针指向子类对象. 二.多态特性 在OC中,调用方法是,会检测对象的真实类型,称为动态绑定. 父类保存子类指针,在调用方法时,有以下步骤: 1).在编译的时候,会检查 父类指向子类的指针 调用的方法,在父类中是否存在,如果有,编译通过 2).在运行时,会动态检测 初始对象 的真实类型 三.多态用途 提供动态绑定特性,减少不必要的程序冗余.在方法中,把父类当成参数,使该方法具备调用所有子类同样方法的能力

学习笔记十二 : squid

一 squid简介 二 squid 安装配置 三 案例