图像SIFT 特征检测与Harris角点检测
目录
1 SIFT 特征检测
1.1 概念
SIFT(尺度不变特征变换)是一种用于图像处理中检测和描述图像中局部结构的算法。它是由David Lowe在1999年提出的,并在2004年进行了详细阐述。SIFT特征具有尺度不变性,这意味着即使图像的尺度发生变化,SIFT特征也能保持稳定。
1.2 主要步骤
尺度空间极值检测:
- 构建尺度空间:通过使用高斯模糊对原始图像进行不同尺度的模糊处理,形成多尺度图像金字塔。
- 检测极值点:在尺度空间中,比较每个点与其周围邻域(包括同一尺度和相邻尺度)的像素值,找出局部极值点。
关键点定位:
- 通过对极值点进行亚像素精度的插值,精确确定关键点的位置和尺度。
- 剔除低对比度的关键点和不稳定的边缘响应点。
方向分配:
- 为每个关键点分配一个或多个方向,使SIFT特征具有旋转不变性。
- 通过计算关键点邻域内的梯度方向直方图,找出主方向和辅方向。
特征描述:
- 在每个关键点周围取一个区域,将这个区域划分为若干个小块。
- 对每个小块计算梯度方向直方图,形成特征向量。
- 为了增强特征的鲁棒性,对特征向量进行归一化处理。
1.3 优缺点
SIFT特征的优点:
- 尺度不变性:能够适应图像的尺度变化。
- 旋转不变性:能够适应图像的旋转变化。
- 对光照、仿射变换和噪声具有一定的鲁棒性。
SIFT特征的缺点:
- 计算复杂度较高,实时性较差。
- 对于非线性变换和大幅度的视角变化,SIFT特征的性能可能会下降。
1.4 函数及参数
sift = cv2.SIFT_create(),创建 SIFT 特征检测器对象
kp = sift .detect(phone_0) ,检测关键点
- phone_0为灰度图
phone_sift = cv2.drawKeypoints(phone,kp,None,flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS), 绘制检测到的关键点
- phone,绘制在的图像
- kp,绘制的关键点
- flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS 表示绘制带有关键点大小和方向的信息
2 Harris角点检测
2.1 概念
Harris 角点检测是一种经典的计算机视觉算法,用于检测图像中的角点。角点是图像中具有显著变化的特征点,通常位于物体的边缘或纹理丰富的区域。Harris 角点检测算法由 Chris Harris 和 Mike Stephens 在 1988 年提出,具有旋转不变性和对噪声的鲁棒性。
2.2 算法思想
Harris角点检测的核心思想是利用局部窗口在图像上进行移动,判断窗口内的灰度值是否发生较大的变化。如果窗口在所有方向上的移动都导致灰度值显著变化,那么这个窗口所在区域就存在角点。
2.3 特点
旋转不变性:角点的检测不受图像旋转的影响。
对噪声鲁棒:通过高斯平滑,算法对噪声具有一定的鲁棒性。
对尺度敏感:Harris 角点检测对图像尺度变化敏感,不适合处理尺度变化较大的场景。
2.4 函数及参数
- cv2.cornerHarris(gray, 4, 3, 0.04), Harris 角点检测图像中的角点
- gray: 输入的灰度图像
- 4: 角点检测的邻域大小
- 3: Sobel 算子的孔径参数
- 0.04: Harris 检测器的自由参数
3 角点、特征检测
3.1 焦点、特征检测代码及结果
代码展示:
import cv2
import numpy as np
img = cv2.imread('fang.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
dst = cv2.cornerHarris(gray,4,3,0.04)
img[dst > 0.01*dst.max()] = [0,0,255]
cv2.imshow('img',img)
cv2.waitKey(0)
phone = cv2.imread('mm.jpg')
phone_0= cv2.cvtColor(phone,cv2.COLOR_BGR2GRAY)
cv2.imshow('phone_0',phone_0)
cv2.waitKey(0)
phone_copy = phone.copy()
dst1 = cv2.cornerHarris(phone_0,4,3,0.04)
phone_copy[dst1 > 0.01*dst1.max()] = [0,0,255]
cv2.imshow('phone',phone_copy)
cv2.waitKey(0)
sift = cv2.SIFT_create()
kp = sift.detect(phone_0)
phone_sift = cv2.drawKeypoints(phone,kp,None,flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
kp,des = sift.compute(phone,kp)
print(np.array(kp).shape,des.shape)
cv2.imshow('phone_sift',phone_sift)
cv2.waitKey(0)
运行结果: