Harris 角点检测

  • 如果是平面,沿着水平或者竖直任意方向移动,其灰度值均无迅速变化
  • 如果是边界,沿着水平或者竖直某个方向,其灰度值变化迅速
  • 如果是角点,无论是水平还是垂直移动,其灰度值应该发生迅速变化

原理

特征向量,模长即长短轴长度,大小影响椭圆大小,代表变化快慢

判断:

最后还有个非极大值抑制。

代码

img = cv2.imread("img.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray_float = np.float32(gray)
dst = cv2.cornerHarris(gray_float, 2, 3, 0.04)
dst = cv2.dilate(dst, None)  # 膨胀角点,优化视觉效果
img[dst > 0.01 * dst.max()] = [0, 0, 255]

SIFT (Scale Invariant Feature Transform)

平移不变性的图像特征匹配算法

流程

生成图像尺度空间

概念

在自然图像中,同一个物体在不同距离或分辨率下的图像是不一样的
在一定范围内,无论物体大小、模糊与否,人眼均可分辨,而计算机很难。
所以如果要让机器能对物体在不同尺度下有一个统一的认知,就需要考虑图像在不同尺度下都存在的特点。

尺度空间是通过对图像进行不同程度的高斯模糊(平滑)得到的一系列图像集合。

高斯滤波:模糊程度

不同的 的高斯函数对图像平滑效果不同,越大越模糊

图像金字塔:图像大小

每一层都有多个高斯滤波结果的图

高斯差分金字塔(DoG)

找到不同模糊程度下差异较大的值,作为特征 D:金字塔差分;G:高斯核,I:原图;L:尺度空间

DoG 空间极值检测

每个像素点与其图像域(同一尺度空间)和尺寸域(相邻尺度空间)的所有相邻点进行比较,当其大于或小于所有相邻点的时候,其为极值点。 每个点和周围 26 个点比较(9 + 8 + 9)

只有上下都有相邻的尺度空间的才能比较,最上最下的无法比较
所以如果想要 n 个比较结果,就要 n+2 层差分,需要 n+3 层高斯模糊

关键点精确定位

将检测到的离散的极值点进行拟合的过程

消除边界响应

高斯滤波可能增加一些边界响应,因此需要我们额外处理,和角点检测类似

特征点表示

把点转化为向量

方向分配

对于每一个点都有以下计算方式: (尺度即模)

对一个特征点进行特征向量生成,要观察其周围的区域的像素点上一步计算的梯度的尺度与方向。 (离散为 8 个方向,或者 10 度一个方向,36 个方向,此处仅用于确定朝向,旋转对齐)

特征描述子生成

每个种子点有 8 个方向的统计直方图,形成一个 8 维向量,共 维。

代码

img = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
sift = cv2.SIFT_create()
keypoints, descriptors = sift.detectAndCompute(img, None)
img_kp = cv2.drawKeypoints(img, keypoints, None,
                        flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)