opencv-python SIFT尺度不变特征变换算法笔记

opencv-python SIFT尺度不变特征变换算法笔记

用DoG(高斯差分算法)提取特征点,并用SIFT描述关键点。

DoG(高斯函数差分算法)提取特征点

高斯函数定义:
在这里插入图片描述
对两幅图像分别进行高斯滤波:
opencv-python SIFT尺度不变特征变换算法笔记_第1张图片
DoG可以表示为:
在这里插入图片描述
第一步,计算不同参数下的DoG:
(1)一个高斯平滑参数为0.3,另一个高斯平滑参数为0.4
opencv-python SIFT尺度不变特征变换算法笔记_第2张图片
(2)一个高斯平滑参数为0.6,另一个高斯平滑参数为0.7
opencv-python SIFT尺度不变特征变换算法笔记_第3张图片
(3)一个高斯平滑参数为0.7,另一个高斯平滑参数为0.8
opencv-python SIFT尺度不变特征变换算法笔记_第4张图片
第二步,根据DoG结果,求角点:
三维图中的最大值和最小值点是角点。
opencv-python SIFT尺度不变特征变换算法笔记_第5张图片
红色点为当前像素点,可与最多26个相邻尺度的点(上层9个+本层8个+下层9个)进行比较,如果它是所邻接像素点的最大值或最小值点,则标记为特征点。依次进行可以完成图像特征点的提取。
通过图1,2,3提取出图2中的极值点。黑色为极小值,白色为极大值。
opencv-python SIFT尺度不变特征变换算法笔记_第6张图片
在原图像上显示DoG角点检测结果
opencv-python SIFT尺度不变特征变换算法笔记_第7张图片

SIFT(尺度不变特征变换算法)

SIFT特征是图像的局部特征 对平移、旋转、尺度缩放、亮度变化、遮挡和噪声等具有良好的不变性,对视觉变化、仿射变换也保持一定程度的稳定性。
·独特性好 信息量丰富,适用于在海量特征数据库中进行快速、准确的匹配。
·多量性 即使少数的几个物体也可以产生大量Sift特征向量。
·速度相对较快 经优化的Sift匹配算法甚至可以达到实时的要求。
·可扩展性强 可以很方便的与其他形式的特征向量进行联合。
Lowe将SIFT算法分解为如下四步:
(1)尺度空间极值检测:搜索所有尺度上的图像位置。通过高斯微分函数来识别潜在的对于尺度和旋转不变的兴趣点。(通过DoG方法提取特征点)

(2)关键点定位:在每个候选的位置上,通过一个拟合精细的模型来确定位置和尺度。
关键点的选择依据于它们的稳定程度。由第①步检测得到的极值点是离散空间的极值点。下面,通过拟合三维二次函数来精确确定关键点的位置和尺度,同时去除低对比度的关键点和不稳定的边缘响应点(因为DoG算子会产生较强的边缘响应),以增强匹配稳定性、提高抗噪声能力。他们使用泰勒级数展开式空间来获得更精确的极值位置,如果这个极值点的强度小于阈值,它就会被拒绝。这个阈值在Opencv中为contrastThreshold。

与Harris角点检测的思路相似,获取特征点处的Hessian矩阵,主曲率(principal curvature)通过一个2x2 的Hessian矩阵H求出:
在这里插入图片描述
在这里插入图片描述
其中α和β分别代表x和y方向的梯度。这里,Tr(H)为主对角线元素之和,Det(H)表示矩阵H的行列式。假设是α较大的特征值,而β为较小的特征值,令α=rβ,则
在这里插入图片描述
D的主曲率和H的特征值成正比,跟上面一样,让α为最大特征值,β为最小特征值,
则公式
在这里插入图片描述
的值在两个特征值相等时最小,随着r的增大而增大。r值越大,说明两个特征值的比值越大,即在某一个方向的梯度值越大,而在另一个方向的梯度值越小,边缘恰恰就是一个方向梯度大,一个方向梯度小的情况。所以为了剔除边缘响应点,需要让该比值小于一定的阈值(论文给的r值为10)将满足条件的关键点保留,否则则扔掉。因此,低对比度和边缘的关键点在本步骤中被去除,只保留最感兴趣的那些点。
opencv-python SIFT尺度不变特征变换算法笔记_第8张图片
(3)方向确定:每个点L(x,y)的梯度的模m(x,y)和方向θ(x,y)
在这里插入图片描述
opencv-python SIFT尺度不变特征变换算法笔记_第9张图片
对其中八个方向进行直方图统计
opencv-python SIFT尺度不变特征变换算法笔记_第10张图片
为了保证特征矢量的旋转不变性,要以特征点为中心,在附近邻域内将坐标轴旋转θ角度,即将坐标轴旋转为特征点的主方向。
opencv-python SIFT尺度不变特征变换算法笔记_第11张图片
opencv-python SIFT尺度不变特征变换算法笔记_第12张图片
(4)关键点描述:在每个关键点周围的邻域内,在选定的尺度上测量图像局部的梯度。这些梯度被变换成一种表示,这种表示允许比较大的局部形状的变形和光照变化。

import cv2
import numpy as np

img = cv2.imread("img/img.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

sift = cv2.xfeatures2d.SIFT_create()
keypoints, descriptor = sift.detectAndCompute(gray, None)

# cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS对图像的每个关键点都绘制了圆圈和方向。
img = cv2.drawKeypoints(image=img, outImage=img, keypoints=keypoints,
                        flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS,
                        color=(51, 163, 236))

cv2.imshow('sift_keypoints', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

opencv-python SIFT尺度不变特征变换算法笔记_第13张图片

参考文章及视频:

https://blog.csdn.net/sss_369/article/details/84674639
https://blog.csdn.net/g11d111/article/details/79925827
https://www.bilibili.com/video/av61678672/?p=12

你可能感兴趣的:(python,opencv,SIFT)