【三维重建】特征检测与匹配
系列文章目录
本系列开始于2022.12.25,开始记录三维重建项目课题研究时的学习笔记,其中主要分为以下几部分组成:
一、相机成像及坐标系之间的转换关系
二、相机标定:张友正标定法
三、特征检测与匹配
四、运动恢复结构法
文章目录:
目录
系列文章目录
文章目录:
前言:
一、特征点前情提要
1.1描述子
1.2 尺度空间与DOG
1.2.1 尺度空间与高斯卷积
1.2.2 DOG金字塔
二、 特征检测
2.1 关键点位置、尺度与方向计算
2.1.1 DOG局部极值点
2.1.2 关键点精准定位
2.1.3 去除边缘响应
2.1.4 关键点的尺度计算
2.1.5 关键点的方向匹配
2.2 特征描述子(向量)的 计算
2.2.1 确定描述子所需图像区域(做准备)
2.2.2 将坐标轴旋转为关键点的方向(先旋转得到编辑)
2.2.3 将关键点邻域内采样点分配到对应的子区域中,将子区域的梯度值分配到8个方向上,计算权值(再将编辑映射到每个小子区域中得到其在每个子区域中的坐标编辑)
2.2.4 双线性插值计算每个采样点对于种子点八个方向的贡献
2.2.5 去除光照影响,归一化处理
2.2.6 描述子向量门限
2.2.7 按特征点的尺度对特征描述向量的排序
2.2.8 总结
三、 代码实现
四、总结
参考:
前言:
在进行相机的参数标定后,使用无人机对数据进行采集,使用采集的无人机图像序列进行三维重建,首先要进行图像序列之间的特征检测与匹配,本文主要记录的是特征检测与匹配相关知识的学习笔记。
一、特征点前情提要
使用图像中选择具有代表性的区域(角点、边缘),进行图像之间的匹配,是常用的方法。在很多的计算机视觉处理中,都是提取角点作为特征,对图像进行匹配,例如SFM,视觉SLAM等。
但是有时候单纯的角点并不能反映图像相应点的全部信息,并且可能由于相机的移动,角点可能会发生改变,这时我们就需要一些不会随着相机的移动,旋转或者光照的变化而变化的特征点。
一个图像的特征点由两部分构成:关键点(Keypoint)和描述子(Descriptor)。 关键点指的是该特征点在图像中的位置,有些还具有方向、尺度信息;描述子通常是一个向量,按照人为的设计的方式,描述关键点周围像素的信息。通常描述子是按照外观相似的特征应该有相似的描述子设计的。因此,在匹配的时候,只要两个特征点的描述子在向量空间的距离相近,就可以认为它们是同一个特征点。
1.1描述子
特征的描述子通常是一个向量,描述了关键点及其周围像素的信息。其具有如下特性:
- 不变性 :指特征不会随着图像的放大缩小旋转而改变。
- 鲁棒性:对噪声、光照或者其他一些小的形变不敏感
- 可区分性:每一个特征描述子都是独特的,具有排他性,尽可能减少彼此间的相似性。
矛盾:其中描述子的可区分性和其不变性是矛盾的,一个具有众多不变性的特征描述子,其区分局部图像内容的能力就比较稍弱;而如果一个很容易区分不同局部图像内容的特征描述子,其鲁棒性往往比较低。所以,在设计特征描述子的时候,就需要综合考虑这三个特性,找到三者之间的平衡。
特征描述子的不变性主要体现在两个方面:
1、尺度不变性 Scale Invarient
同一特征在同一图像的不同尺度下保持不变。 为了保持尺度的不变性,在计算特征点的描述子的时候,通常将图像变换到统一的尺度空间,再加上尺度因子。没有此特征,同一个特征点在放大或者缩小的图像间,就不能很好的匹配。
2、旋转不变性 Rotation Invarient
指的是同一个特征,在成像视角旋转后,特征仍然能够保持不变。和尺度不变性类似,为了保持旋转不变性,在计算特征点描述子的时候,要加上关键点的方向信息。
以下为常用的描述子的计算方法:(本文主要介绍SIFT的计算方法)
1.2 尺度空间与DOG
1.2.1 尺度空间与高斯卷积
上文中多次提到了尺度、尺度空间,在此解释一下其含义。
先回顾二维高斯函数表达式:
当我们使用不同σ值的高斯函数对一张图像进行卷积时,就产生了多张不同σ值的高斯图像, 这里的σ值就是不同的尺度。
可以理解为它是计算机观测图片的远近程度:当我们观察一张图片时,离图像越远,图像越模糊;我们都知道可以使用不同的高斯卷积核对图像进行低通滤波,减少图像细节信息,使图像变模糊,就类似与人眼观测图像,而且高斯滤波器宽度(决定着平滑程度)是由参数σ表征的,而且σ和平滑程度有关。
所以,尺度就是二维高斯函数当中的σ值,所有不同尺度下的图像,构成单个原始图像的尺度空间。“图像尺度空间表达”就是图像在所有尺度下的描述。
尺度是自然客观存在的,不是主观创造的。高斯卷积只是表现尺度空间的一种形式。
尺度空间表达式:
高斯卷积核如图:
位于卷积核中心的原始像素值有最大的权重,距离中心越远的相邻像素值权重也越小。
前面提到的高斯卷积使图像变模糊类似于人眼距离图像很远的时候会模糊,但是人知道知道物体的关键轮廓即可知道物体的信息,所以计算机也可通过这些关键信息,来识别图像。
1.2.2 DOG金字塔
在介绍DOG金字塔之前,我们先来了解一下金字塔:
对图像进行降采样,图像包含像素点和图像的尺寸会随之减少。在多次进行降采样后将得到的结果叠在一起就形成了一个金字塔。注意上图的金子塔是通过对底层的fine图像进行降采样得到的。
这里的金字塔和尺度空间表达的区别就在于:
1、图像金字塔的每层的分辨率减少了,而尺度空间的分辨率是不变的。
2、图像金字塔的处理速度随着分辨率的下降而加快。
为了让尺度体现其连续性,得到了一种比较中和的方法,将图像金字塔和尺度空间表达进行融合,就得到了LOG(Laplassian of Gaussian)金字塔。
先将照片降采样,得到了不同分辨率下的图像金字塔,再对每层图像进行高斯卷积。最后得到的结果就是在金字塔的基础上每一层都有不同尺度的相同分辨率图像。将金字塔每层多张图像合称为一组(Octave),金字塔每层只有一组图像,组数和金字塔层数相等,每组含有多层Interval图像。
最后根据LOG生成DOG。
k为相邻两尺度空间倍数的常数。将图像金字塔分为O组,一组称为一个Octave,每组又分为多层,层间隔数为S,因此有S+3(S+1+2,2代表在上下再各添一层图像,搜索极值只在中间的S+1层图像上搜索)层图像,下一组的图像由上一组的倒数第三层(如果层索引从0开始,则为第S层)图像降采样得到(为了减少卷积运算的工作量),然后用LOG金字塔(下图左)每一层的相邻的图像进行相减,得到所有图像重新构造的金字塔就是DOG金字塔(下图右)。
在上述尺度空间中,O和S,的关系如下:
其中是基准层尺度,o为组octave的索引,s为组内层的索引。关键点的尺度坐标就是按关键点所在的组和组内的层,利用上式计算而来。
在最开始建立金字塔时,要预先模糊输入图像来作为第0个组的第0层的图像,这时相当于丢弃了最高的空域的采样率。因此通常的做法是先将图像的尺度扩大一倍来生成第-1组。我们假定初始的输入图像为了抗击混淆现象,已经对其进行的高斯模糊,如果输入图像的尺寸用双线性插值扩大一倍,那么相当于
。
取:
在构建高斯金字塔时,组内每层的尺度坐标按如下公式计算:
不同组相同层的组内尺度坐标相同。组内下一层图像是由前一层图像
按进行高斯模糊所得。上式用于一次生成组内不同尺度的高斯图像,而在计算组内某一层图像的尺度时,直接使用如下公式进行计算:
该组内尺度在方向分配和特征描述时确定采样窗口的大小。最后得到:
二、 特征检测
2.1 关键点位置、尺度与方向计算
2.1.1 DOG局部极值点
关键点是由DOG空间的局部极值点组成的。
在图像中每个像素和其周围的像素进行比较,当其像素值大于或者小于所有相邻点时,即为极值点。在DOG金字塔中,周围的像素点不止为当前这一层的一个尺度差值图像上周围的点,这一层中一个点中的不同尺度差值图像也要考虑在内。
中间的检测点和它同尺度的8个相邻点和上下相邻尺度对应的9×2个 点共26个点比较,以确保在尺度空间和二维图像空间都检测到极值点。
上述方法求出来的是离散空间中的极值点,需要通过拟合三维二次函数来精确确定关键点的位置和尺度,同时去除低对比度的特征点和不稳定的边缘响应点(因为DOG算子会产生较强的边缘响应),以增强匹配稳定性、提高抗噪声能力。
2.1.2 关键点精准定位
利用DOG函数在尺度空间的Taylor展开式(拟合函数)为:
其中。对方称求导并使其等于零得到极值点的偏移量:
此偏移量代表的是相对插值中心的偏移量,当它在任一维度上的偏移量大于0.5时(即x或y或),意味着插值中心已经偏移到它的邻近点上,所以必须改变当前关键点的位置。改变位置之后再在新的位置上反复插值,直到收敛,若超出了迭代次数或者图像范围,则判定此点应该删除。
将极值点带入方程:
2.1.3 去除边缘响应
根据Harris角点可以知道,一个角点在任何方向上平移都应该保证局部窗口内的像素值的剧烈变化,而边缘上的点沿着边缘方向移动时局部窗口内的像素值基本没有什么变化。一个定义不好的高斯差分算子的极值在横跨边缘的地方有较大的主曲率,而在垂直边缘的方向有较小的主曲率。DOG算子会产生较强的边缘响应,因此需要剔除不稳定的边缘响应点。
首先我们获取特征点出的海森(Hessian)矩阵,
H的特征值与D的主曲率成正比例。可以避免求取具体的特征值,因为我们只关心特征值的比例。H的特征值α(较大)和β(较小)代表x和y方向的梯度:
Tr(H)表示矩阵H对角线元素之和,Det(H)表示矩阵H的行列式。假设是α较大的特征值,而是β较小的特征值,令,则:
这样我们便得到了一个只关于两个特征向量的比值有关的公式,与具体的特征值无关,当两个特征值相等的时候(
= 1)上式达到最小,
越大,上式也越大。
越大就证明在某一方向的梯度越大,另一方向的梯度越小,这样为了防止出现上面所说的:横跨边缘的地方有较大的主曲率,而在垂直边缘的方向有较小的主曲率的情况,我们设定一个
的阈值,这样我们只需要检查:
满足条件即认为可以保留。
2.1.4 关键点的尺度计算
在1.2.2中已经介绍:
组内每层的尺度坐标按如下公式计算:
上式用于一次生成组内不同尺度的高斯图像,而在计算组内某一层图像的尺度时,直接使用如下公式进行计算:
2.1.5 关键点的方向匹配
为了实现描述符的旋转不变性,利用图像的局部特征为每一个关键点求取一个方向,使用图像梯度方向求取局部结构的稳定方向。对于已经检测到的关键点,我们知道该点在DOG金字塔中的位置和尺度,在与尺度相应的高斯图像上使用有限差分(参考6中4.3详细介绍了),计算已特征点为中心,其所在高斯金字塔图像邻域窗口内像素的幅值和角度:
梯度的模值m(x,y)按的高斯分布加成,按尺度采样的3σ原则,所以邻域窗口半径为
。
在完成关键点邻域的高斯图像的梯度计算后,使用直方图统计邻域内像素的梯度方向和幅值。梯度方向直方图的横轴是梯度方向角,纵轴是梯度方向角对应的梯度幅值累加。梯度方向直方图将0-360度的范围分为36个柱(bins),每10度一个柱。直方图的峰值代表该关键点处邻域内图像梯度的主方向,也即该关键点的主方向:
为了增强匹配的鲁棒性,只保留峰值大于主方向峰值80%的方向作为该关键点的辅方向。SIFT作者Lowe的论文指出大概有15%关键点具有多方向,但这些点对匹配的稳定性至为关键。
2.2 特征描述子(向量)的 计算
通过以上步骤,对于每一个关键点,拥有三个信息:位置、尺度以及方向。接下来就是为每个关键点建立一个描述符,用一组向量将这个关键点描述出来,使其不随各种变化而改变,比如光照变化、视角变化等等。特征描述子与特征点所在的尺度有关,因此,对梯度的求取应在特征点对应的高斯图像上进行。
SIFT描述子时关键点邻域的高斯图像梯度统计结果的一种表示,通过对周围像素分块计算块内的梯度直方图,生成对于此块图像信息的一种独特的,抽象的,唯一的向量。
Lowe在文中说明描述子使用在关键点尺度空间内4×4的窗口中计算8个方向的梯度值,共4×4×8 = 128维向量。
主要表述步骤有以下几个:
2.2.1 确定描述子所需图像区域(做准备)
将关键点附近邻域分割维d×d(4×4)个子区域,每个子区域作为一个种子点,种子点有8个方向,即相当于每个子区域有8个方向,后面根据采样点计算这8个方向的权值。
每个子区域的大小与关键点方向分配时相同,即每个区域有个子像素,按需每个子区域使用边长为
的矩形区即可包围,但
并不大,并且采样点宜多不宜少,为了简化计算取其边长
,所以为每个子区域分配边长为
的矩形区域进行采样。
考虑到后续需要采用双线性插值所以所需图像窗口边长为:。并且考虑旋转因素 (方便下一步将坐标轴旋转到关键点的方向,下一步介绍),如下图所示,实际计算所需的图像区域半径为(计算结果四舍五入取整):
2.2.2 将坐标轴旋转为关键点的方向(先旋转得到
)
为保证旋转不变性,即将坐标轴旋转到关键点的方向。左图为没旋转之前,在图中红箭头标志的是当前的关键点的方向,右图是旋转以后。
旋转后的邻域内采样点的新坐标为:
2.2.3 将关键点邻域内采样点分配到对应的子区域中,将子区域的梯度值分配到8个方向上,计算权值(再将
映射到每个小子区域中得到其在每个子区域中的坐标
)
将旋转后的采样点坐标在半径为radius的圆内分配到d×d(4×4)个子区域,计算影响子区域的采样点的梯度和方向,分配到8个方向上。
旋转后的采样点落在子区域的下标为
的位置:
其中是在第一步做准备中得到的每个子区域的边长,d是后期进行双线性采样的参数。Lowe建议子区域的像素的梯度大小按
的高斯加权计算,即
其中a,b为关键点在高斯金字塔图像中的位置坐标。
2.2.4 双线性插值计算每个采样点对于种子点八个方向的贡献
分配在子区域下标为,例如上图中的红点,即为分配在最右上角子区域中的一点,对其进行线性插值,计算其对每个种子点(每个子区域都作为一个种子点)的贡献。
如图中的红色点,落在第0行和第1行之间,对这两行都有贡献。对第0行第3列种子点的贡献因子为dr,对第1行第3列的贡献因子为1-dr,同理,对邻近两列的贡献因子为dc和1-dc,对邻近两个方向的贡献因子为do和1-do。则最终累加在每个方向上的权值大小为:
其中k,m,n为0或为1。在此说明,此点在0行3列,假设方向为6,则对应的给hist[0][3][6]加上相应的权值。
2.2.5 去除光照影响,归一化处理
通过以上步骤我们就得到了关键点尺度空间内4×4的窗口中8个方向的梯度值,共4×4×8 = 128维向量H。接下来对图像进行归一化处理:
其中,为归一化之前得到的128维向量,
为归一化后的结果。
2.2.6 描述子向量门限
非线性光照,相机饱和度变化会造成某些方向的梯度值过大,因此设置门限值(向量归一化后,一般取0.2)截断较大的梯度值。然后,再进行一次归一化处理,提高特征的鉴别性。
2.2.7 按特征点的尺度对特征描述向量的排序
按特征点的尺度对特征描述向量进行排序。
2.2.8 总结
至此,SIFT特征描述向量生成,总结归纳为:为描述向量的计算进行范围的划分后, 先旋转得到, 再将
映射到每个小子区域中得到其在每个子区域中的坐标
,双线性插值计算每个采样点对于子区域(种子点)八个方向的权值(贡献),归一化处理并设置门限,最后按特征点的尺度对特征描述向量进行排序。
三、 代码实现
因为SIFT在后期申请了版权所以在低版本时可以使用cv2.xfeatures2d.SIFT_create()进行创建SIFT描述子,OpenCV 3.4之后因专利版权问题移除了SIFT/SURF的相关库,因此在使用较新版本的cv库时会报错。
sift = cv2.xfeatures2d.SIFT_create()
key_points, desc = sift.detectAndCompute(img, None)
函数返回关键点和特征向量。
关键点包含的信息有:
pt:关键点点的坐标
angle:角度,表示关键点的方向,通过Lowe大神的论文可以知道,为了保证方向不变形,SIFT算法通过对关键点周围邻域进行梯度运算,求得该点方向。-1为初值。
size:该点直径的大小
class_id:当要对图片进行分类时,我们可以用class_id对每个特征点进行区分,未设定时为-1,需要靠自己设定
octave:代表是从金字塔哪一层提取的得到的数据。
response:响应程度,确切的说,是该点角点的程度。
四、总结
本篇介绍了怎么对图像的特征进行提取,提取了特征以后,在匹配的时候,只要两个特征点的描述子在向量空间的距离相近,就可以认为它们是同一个特征点。
参考:
1、http://t.csdn.cn/OSm5h
2、http://t.csdn.cn/JyupC
3、http://t.csdn.cn/P12m0
4、SLAM入门之视觉里程计(1):特征点的匹配 - Brook_icv - 博客园 (cnblogs.com)
5、http://t.csdn.cn/5TLRn
6、http://t.csdn.cn/KWgLE
【三维重建】特征检测与匹配相关推荐
- 特征检测与匹配,测试8点法求取基础矩阵F(三维重建task1-3)
特征检测与匹配(三维重建task1-3) #include <math/matrix_svd.h> #include "math/matrix.h" #include ...
- OpenCV基础(23)特征检测与匹配
图像的8x8像素部分被考虑,并将这个 8x8 框进一步划分为 4 个块,每个块为 4x4 维度.在每个 4x4 块内,图像梯度以向量的形式表示.通过搜索最独特或不同的特征在图像中找到关键点.这里,Ke ...
- 数字图像处理学习笔记(一):特征检测和匹配概述
数字图像处理学习笔记(一):特征检测和匹配概述 参考博客: 特征点的匹配 SIFT特征详解 数字图像处理学习笔记(二):SIFT(尺度不变特征变换)算法 1.特征点概述 如何高效且准确的匹配出两个不同 ...
- SLAM中的 ORB特征检测与匹配(理论篇)
<SLAM十四讲>视觉里程计第一部分的实践便是ORB特征检测 下面来讲讲ORB的理论: ORB算法分为两部分,第一部分是特征提取算法即FAST算法,第二部分是特征描述子BRIEF,BRIE ...
- sift特征检测与匹配
文章目录 一 实验背景 1.sift算法介绍 1.1sift算法特点 1.2sift算法可以解决的问题 1.3 sift算法实现具体步骤 2.关键点相关概念 2.1关键点(特征点) 2.2尺度空间 3 ...
- 三维重建 影像匹配 密集匹配三者的关系
三维测重建:1 基于体元 2 基于面元 3 基于四面体 4 基于平面扫描 5 基于线特征 6 基于深度图 密集匹配:在影像中逐像素的寻找尽可能多的同名点的一项技术.成果为深度图. 影像匹配:通过一 ...
- ORB 特征检测与匹配
#include <opencv2/opencv.hpp> #include <opencv2/xfeatures2d.hpp> #include <opencv2/xf ...
- SURF 特征检测及匹配
#include <opencv2/opencv.hpp> #include <opencv2/xfeatures2d.hpp> #include <opencv2/xf ...
- SIFT 特征检测及匹配
#<opencv2/opencv.hpp> #include <opencv2/features2d/features2d.hpp> #include <opencv2/ ...
- OpenCV——KAZE、AKAZE特征检测、匹配与对象查找
AKAZE是KAZE的加速版 特征点查找和绘制:把surf中的surf改成KAZE或AKAZE即可 1 #include <opencv2/opencv.hpp> 2 #include ...
最新文章
- 【Spring】通过动态代理改进银行转账事务控制
- echarts学习文档
- centos7安装Tomacat以及自动启动
- C++找出一个二维数组中的鞍点,即该位置上的元素在该行上最大,在该列上最小(也可能没有鞍点)
- 快手 算法工程师 0825 笔试题
- 国外一些知名ASP.Net开源CMS系统
- SpringCloud学习笔记023---分布式集群之_Windows下搭建zookeeper服务器
- [3G/4G]3G/4G模块开发
- 分布式,集群,冗余的理解
- 好用的qq群管机器人插件 附教程
- Echart中series自定义formatter文字样式
- 如何清理roaming_笔记本电脑中appdata中roaming怎么越来越大该怎么办
- 修正半透明头发的渲染异常
- 温故而知新,可以为师矣
- Python-定时爬取指定城市天气(一)-发送给关心的微信好友
- 带你学会C++文字页面类项目——4.整体完善与项目1
- python 处理Bus Hound 数据
- php var的解释
- Apache Doris 向量化版本在小米A/B实验场景的调优实践
- 使用javascript让图片人物动起来