特征检测

opencv可以检测图像的主要特征,然后提取这些特征,使其成为图像描述符。

特征:特征就是有意义的图像区域,该区域具有独特性或易于识别性。角点与高密度区域是一个很好的特征,边缘可以将图像分为两个区域,因此可以看作很好的特征,斑点(与周围有很大区别的图像区域)也是有意义的特征。

大多数特征检测算法都会涉及图像的角点、边和斑点的识别。

Harris可用于识别角点。此函数可以很好的检测角点,这些角点在图像旋转的情况下也能被检测到。但是如果减少或者增加图像的尺寸,可能会丢失图像的某些部分,也有可能增加图像的角点。这种特征损失的现象需要一种与图像比例无关的检测方法解决。这就是SIFT,可以对不同图像尺寸输出相同的结果。SIFT会通过一个特征向量来描述关键点周围区域的情况。Dog用于检测关键点。

SURF算法比SIFT快好几倍,它吸收了SIFT算法的思想。SURF采用Hessian算法检测关键点。SURF需要提供阈值,特征随着阈值的增加而减少。

ORB是用来取代SIFT和SURF的,与两者相比,ORB有更快的速度。ORB用FAST来检测关键点,用BRIEF来进行关键点特征描述。

有点迷糊,现在总结一下

opencv中的SIFT是DoG与SIFT的结合。DoG用于关键点的检测,SIFT用于描述关键点的特征(图像描述符)。

SURF是Hessian与SURF的结合,Hessian用于关键点的检测,SURF用于描述关键点的特征。

ORB是FAST和BRIEF的结合,FAST用于关键点的检测,BRIEF用于描述关键点的特征。

速度上ORB>SURF>SIFT,SURF的鲁棒性(抗干扰能力)更好一些。

SIFT

Scale Invariant Feature Transform,尺度不变特征变换。SIFT特征对旋转、尺度缩放、亮度变化等保持不变性,是一种非常稳定的局部特征。

SIFT算法主要有以下几个步骤:

高斯差分金字塔的构建
使用组和层的结构构建了一个具有线性关系的金字塔(尺度空间),这样可以在连续的高斯核尺度上查找图像的特征点;另外,它使用一阶的高斯差分来近似高斯的拉普拉斯核,大大的减少了运算量。
尺度空间的极值检测及特征点的定位
搜索上一步建立的高斯尺度空间,通过高斯差分来识别潜在的对尺度和旋转不变的特征点。但是,在离散空间中,局部极值点可能并不是真正意义的极值点,真正的极值点有可能落在离散点的间隙中,SIFT通过尺度空间DoG函数进行曲线拟合寻找极值点。
特征方向赋值
基于图像局部的梯度方向,分配给每个关键点位置一个或多个方向,后续的所有操作都是对于关键点的方向、尺度和位置进行变换,从而提供这些特征的不变性。
特征描述子的生成
通过上面的步骤已经找到的SIFT特征点的位置、方向、尺度信息,最后使用一组向量来描述特征点及其周围邻域像素的信息。

SURF

Speeded Up Robust Features。加速版的SIFT。

SURF的流程和SIFT比较类似,这些改进体现在以下几个方面:

特征点检测是基于Hessian矩阵,依据Hessian矩阵行列式的极值来定位特征点的位置。并且将Hession特征计算与高斯平滑结合在一起,两个操作通过近似处理得到一个核模板。
在构建尺度空间时,使用box filter与源图像卷积,而不是使用DoG算子。
SURF使用一阶Haar小波在x、y两个方向的响应作为构建特征向量的分布信息。

FAST

Features From Accelerated Segment Test,以速度快而著称

检测局部像素灰度变化明显的地方,

FAST算法提取角点的步骤:

在图像中选择像素p,假设其灰度值为:Ip
设置一个阈值T,例如:Ip的20%
选择p周围半径为3的圆上的16个像素,作为比较像素
假设选取的圆上有连续的N个像素大于Ip+T或者Ip−T,那么可以认为像素p就是一个特征点。(N通常取12,即为FAST-12;常用的还有FAST-9,FAST-11)。
不可避免的也有一些缺点

检测到的特征点过多并且会出现“扎堆”的现象。这可以在第一遍检测完成后,使用非最大值抑制(Non-maximal suppression),在一定区域内仅保留响应极大值的角点,避免角点集中的情况。
FAST提取到的角点没有方向和尺度信息
上面的介绍的SIFT和SURF算法都包含有各自的特征点描述子的计算方法,而FAST不包含特征点描述子的计算,仅仅只有特征点的提取方法,这就需要一个特征点描述方法来描述FAST提取到的特征点,以方便特征点的匹配。下面介绍一个专门的特征点描述子的计算算法。

BRIEF描述子

BRIEF是一种二进制的描述子,其描述向量是0和1表示的二进制串。0和1表示特征点邻域内两个像素(p和q)灰度值的大小:如果p比q大则选择1,反正就取0。在特征点的周围选择128对这样的p和q的像素对,就得到了128维由0,1组成的向量。那么p和q的像素对是怎么选择的呢?通常都是按照某种概率来随机的挑选像素对的位置。
BRIEF使用随机选点的比较,速度很快,而且使用二进制串表示最终生成的描述子向量,在存储以及用于匹配的比较时都是非常方便的,其和FAST的搭配起来可以组成非常快速的特征点提取和描述算法。

ORB

Oriented FAST and Rotated BRIE

使用非最大值抑制,在一定区域内仅仅保留响应极大值的角点,避免FAST提取到的角点过于集中。
FAST提取到的角点数量过多且不是很稳定,ORB中可以指定需要提取到的角点的数量N,然后对FAST提取到的角点分别计算Harris响应值,选择前N个具有最大响应值的角点作为最终提取到的特征点集合。
FAST提取到的角点不具有尺度信息,在ORB中使用图像金字塔,并且在每一层金字塔上检测角点,以此来保持尺度的不变性。
FAST提取到的角点不具有方向信息,在ORB中使用灰度质心法(Intensity Centroid)来保持特征的旋转不变性。

FAST-12算法:

添加预测试操作,于每个像素,直接检测在邻域圆上的第1,5,9,13个像素的亮度,只有当这四个像素当中有三个同时大于IP+T或者小于IP-T的时候,当前像素才有可能是是角点。

问题1:FAST特征点的数量很多,并且不是确定,而大多数情况下,我们希望能够固定特征点的数量。

解决方法:在ORB当中,我们可以指定要提取的特征点数量。对原始的FAST角点分别计算Harris的响应值,然后选取前N个点具有最大相应值的角点,作为最终角点的集合。

问题2:FAST角点不具有方向信息和尺度问题。

解决方法:尺度不变性构建的图像的金字塔,并且从每一层上面来检测角点。旋转性是由灰度质心法实现。

灰度质心法:质心是指以图像块灰度值作为权重的中心。(目标是为找找到方向)

1、在一个小的图像块B中,定义图像块的矩为:


 
2、通过矩找到图像块的质心


 
3、连接图像块的几何中心o与质心C,得到一个oc的向量,把这个向量的方向定义特征点的方向

特征匹配

1.暴力(Brute-Force)匹配:一种描述符匹配算法,该方法会比较两个描述符,并产生匹配结果列表,第一个描述符的所有特征都拿来和第二个进行比较。

2.K-最近邻(knn)匹配:在所有的机器学习suan算法中,knn可能是最简单的。

.FLANN匹配:FLANN具有一种内部机制,该机制可以根据数据本身选取合适的算法来处理数据集,FLANN比其他的最近邻搜索快10倍。

.FLANN的单应性匹配,单应性指的是两幅图像中的一幅出现投影畸变时,他们还能彼此匹配。

SURF SIFT ORB三种特征检测算法比较

双目立体测距的基础是利用视差求距离,而视差就是计算左右图像中对应点的像素坐标之差,这个左右图中的对应点是由通过立体匹配得来。

立体匹配从大的方面说分为两种,全局匹配和局部匹配,全局匹配精度高,但是计算速度慢,不能满足实时的要求,局部匹配速度快,可以满足实时的要求,但是精度不如前者,考虑到项目实际,需要实时的判断机器人与环境的关系,就重点研究局部匹配。局部匹配又分为基于区域的匹配,基于特征的匹配以及基于梯度的优化方法。综合比较,选择基于特征的匹配。

基于特征的匹配分为特征点提取和匹配两个步骤,下面主要针对特征点提取三种方法进行比较,分别是SIFT,SURF以及ORB三种方法,这三种方法在OpenCV里面都已实现。SURF基本就是SIFT的全面升级版,有 SURF基本就不用考虑SIFT,而ORB的强点在于计算时间,以下具体比较:

计算速度:            ORB>>SURF>>SIFT(各差一个量级)

旋转鲁棒性:        SURF>ORB~SIFT(表示差不多)

模糊鲁棒性:        SURF>ORB~SIFT

尺度变换鲁棒性: SURF>SIFT>ORB(ORB并不具备尺度变换性)

所以结论就是,如果对计算实时性要求非常高,可选用ORB算法,但基本要保证正对拍摄;如果对实行性要求稍高,可以选择SURF;基本不用SIFT。

OpenCV 接口
1、OpenCV中封装了常用的特征点算法(如SIFT,SURF,ORB等),提供了统一的接口,便于调用。

#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
 
int main()
{
    //0读取图像
    Mat img1 = imread("1.png");
    Mat img2 = imread("2.png");
    // 1 初始化特征点和描述子,ORB
    std::vector<KeyPoint> keypoints1, keypoints2;
    Mat descriptors1, descriptors2;
    Ptr<ORB> orb = ORB::create();
    // 2 提取 Oriented FAST 特征点
    orb->detect(img1, keypoints1);
    orb->detect(img1, keypoints1);
    // 3 根据角点位置计算 BRIEF 描述子
    orb->compute(img1, keypoints1, descriptors1);
    orb->compute(img2, keypoints2, descriptors2);
    // 4 对两幅图像中的BRIEF描述子进行匹配,使用 Hamming 距离
    vector<DMatch> matches;
    BFMatcher bfmatcher(NORM_HAMMING);
    bfmatcher.match(descriptors1, descriptors2, matches);
    // 5 绘制匹配结果
    Mat img_match;
    drawMatches(img1, keypoints1, img2, keypoints2, matches, img_match);
    imshow("所有匹配点对", img_match);
    waitKey(0);
    return 0;
}
得到了描述子后,可调用匹配算法进行特征点的匹配。上面代码中,使用了opencv中封装后的暴力匹配算法BFMatcher,该算法在向量空间中,将特征点的描述子一一比较,选择距离(上面代码中使用的是Hamming距离)较小的一对作为匹配点。

DMatch类存放匹配结果

struct DMatch
{       
          int queryIdx;  //此匹配对应的查询图像的特征描述子索引
          int trainIdx;   //此匹配对应的训练(模板)图像的特征描述子索引
          int imgIdx;    //训练图像的索引(若有多个)
          float distance;  //两个特征向量之间的欧氏距离,越小表明匹配度越高。
          bool operator < (const DMatch &m) const;
};
匹配函数match

match(descriptors1, descriptors2, matches);
 matches中保存着匹配关系

画匹配图像drawMatches

drawMatches(img1, keypoints1, img2, keypoints2, matches, img_match);
 img_match为目标图像。

2、筛选:汉明距离小于最小距离的两倍
选择已经匹配的点对的汉明距离小于最小距离的两倍作为判断依据,如果小于该值则认为是一个错误的匹配,过滤掉;大于该值则认为是一个正确的匹配。

// 匹配对筛选
    double min_dist = 1000, max_dist = 0;
    // 找出所有匹配之间的最大值和最小值
    for (int i = 0; i < descriptors1.rows; i++)
    {
        double dist = matches[i].distance;//汉明距离在matches中
        if (dist < min_dist) min_dist = dist;
        if (dist > max_dist) max_dist = dist;
    }
    // 当描述子之间的匹配大于2倍的最小距离时,即认为该匹配是一个错误的匹配。
    // 但有时描述子之间的最小距离非常小,可以设置一个经验值作为下限
    vector<DMatch> good_matches;
    for (int i = 0; i < descriptors1.rows; i++)
    {
        if (matches[i].distance <= max(2 * min_dist, 30.0))
            good_matches.push_back(matches[i]);
    }

SLAM中的图像配准

实时性必须强,速度必须要快,可以在质量和速度之间折中

■    SIFT,SURF等特征提取方法具有较好的并行性,可通过GPU等设备加速运算,如加速后的SIFT就满足实时性的要求。
■    在目前的SLAM方案中,ORB是质量与性能之间较好的折中
■    ORB在平移、旋转、缩放的变换下仍具有较好的表现
■    FAST和BRIEF的组合非常高效
■    匹配的时候采用快速近似最近邻

参考:https://blog.csdn.net/qq_28901541/article/details/88817122

特征检测与特征匹配算法简介相关推荐

  1. ML之FE:数据处理—特征工程之稀疏特征的简介、如何处理、案例应用之详细攻略

    ML之FE:数据处理-特征工程之稀疏特征的简介.如何处理.案例应用之详细攻略 目录 稀疏特征的简介 稀疏特征的如何处理 稀疏特征的案例应用 稀疏特征的简介 信号稀疏表示是过去近20年来信号处理界一个非 ...

  2. OpenCV入门学习笔记之Harris角点检测与SIFT特征匹配算法

    1. 写在前面 这篇文章整理两个图像处理中非常重要的算法,一个是Harris角点检测算法,另一个是SIFT特征匹配算法,这两个算法本质上还是去找图像里面的关键特征点,帮助我们后续更好的理解图像以及做各 ...

  3. LGP (Local Gradient Patterns)特征匹配算法

    **写在前面:**由于在读论文时看到了LGP算法,在网上没有找到相关原理解释,所以写篇博客记录一下,方便有需要的同学学习. LGP (Local Gradient Patterns)特征匹配算法的原理 ...

  4. 特征检测和特征匹配方法

    特征检测和特征匹配方法 一幅图像中总存在着其独特的像素点,这些点我们可以认为就是这幅图像的特征,成为特征点.计算机视觉领域中的很重要的图像特征匹配就是一特征点为基础而进行的,所以,如何定义和找出一幅图 ...

  5. OpenCV精进之路(十五):特征检测和特征匹配方法汇总

    一幅图像中总存在着其独特的像素点,这些点我们可以认为就是这幅图像的特征,成为特征点.计算机视觉领域中的很重要的图像特征匹配就是一特征点为基础而进行的,所以,如何定义和找出一幅图像中的特征点就非常重要. ...

  6. 特征检测和特征匹配方法汇总

    一幅图像中总存在着其独特的像素点,这些点我们可以认为就是这幅图像的特征,成为特征点.计算机视觉领域中的很重要的图像特征匹配就是一特征点为基础而进行的,所以,如何定义和找出一幅图像中的特征点就非常重要. ...

  7. 【深度学习】FPN(特征金字塔)简介:Feature Pyramid Networks for Object Detection

    [深度学习]FPN(特征金字塔):Feature Pyramid Networks for Object Detection 提示:博主取舍了很多大佬的博文并亲测有效,分享笔记邀大家共同学习讨论 博文 ...

  8. 论文速递:一种用于视觉定位的基于NLP思路的直线特征匹配算法

    标题:Line as a Visual Sentence:Context-aware Line Descriptor for Visual Localization 作者:Sungho Yoon1 a ...

  9. 基于haar特征的adaboost算法_SuperGlue一种基于图卷积神经网络的特征匹配算法

    ETHZ ASL与Magicleap联名之作,CVPR 2020 Oral(论文见文末),一作是来自ETHZ的实习生,二作是当年CVPR2018 SuperPoint 的作者Daniel DeTone ...

最新文章

  1. Accessing tools within a VB6 program - AE中使用VB调用Geoprocessing
  2. linux软件包管理-rpm
  3. 什么是 SAP C/4HANA Foundation
  4. mount --bind的用处
  5. C++ 读入一行字符串
  6. 探讨如何确保对日软件外包开发过程中的质量
  7. python ansible模块_Python之——Ansible常用模块及API,pythonansibleapi
  8. tcp实时传输kafka数据_关于Kafka producer管理TCP连接的讨论
  9. Python开发入门与实战14-基于Extjs的界面
  10. SparkStreaming手动维护Kafka Offset的几种方式
  11. spring-aspectj的几个aop注解
  12. linux界面三个图标,配置Ubuntu Enlightenment桌面环境之三:桌面图标和根菜单_Linux学院_风信网...
  13. SQL Server中Rowcount与@@Rowcount的用法 和set nocount on 也会更新@@Rowcount
  14. docker构建mysql容器及Navicat 远程连接
  15. 9.2. service
  16. 自考计算机毕业论文范文,计算机信息论文范文 计算机信息类有关自考毕业论文范文5000字...
  17. 【前端】虚拟键盘的简单运用
  18. 语音-MFCC,Fbank特征提取
  19. Android 4.0.4系统下实现apk的静默安装和启动
  20. 弧形银幕电影的成像原理

热门文章

  1. 深度学习(波士顿房价预测)
  2. 使用线性回归实现波士顿房价预测
  3. WEB QQ 网页登陆QQ QQ的HTTP接口探究
  4. Android屏幕点亮(常亮)及屏幕解锁和锁定
  5. ◎ 增量更新jar包,报错问题(It has been compressed and nested jar files must be stored without compression)
  6. 脑结构-功能耦合解码大脑状态和个体指纹
  7. JAVA生成二维码-zxing
  8. Android adb模拟走步,某 APP 跑步模块性能测试
  9. 如何使用JS实现图片幻灯片自动播放
  10. 推广引流方法有哪些?