Harris角点检测
概念
Harris角点检测是一种在图像处理和计算机视觉领域广泛使用的技术,用于检测图像中的角点。角点是图像中两条边缘交点的位置,它们在图像分析、目标识别和图像配准等任务中非常重要。
角点:图像中的角点是指图像局部区域内,两条边缘或边界交会的点。在角点处,图像的梯度方向会发生显著变化。
Harris角点检测器:Harris角点检测器是一种基于梯度的方法,用于识别图像中的角点。它通过计算图像强度函数的局部自相关矩阵来工作。
原理
Harris角点检测的基本原理可以概括为以下几个步骤:
-
图像的预处理:通常包括将图像转换为灰度图,因为角点检测不依赖于颜色信息。
-
计算梯度:对图像应用Sobel算子或其他梯度算子,计算图像每个像素点的梯度值和梯度方向。
-
构造结构张量(结构矩阵):结构张量是一个2x2的矩阵,它量化了图像在每个像素点的梯度变化。对于每个像素点,计算其邻域内的梯度值,并构造结构张量 MM 。
-
计算特征值:计算结构张量的两个特征值。角点处的特征值会显著不同,因为角点处的边缘在两个方向上都有显著的梯度变化。
-
应用Harris检测公式:Harris检测公式用于评估每个像素点成为角点的可能性。公式如下:
R=det(M)−k(trace(M))2R=det(M)−k(trace(M))2
其中,det(M)det(M) 是矩阵 MM 的行列式,trace(M)trace(M) 是矩阵 MM 的迹,kk 是一个经验常数,通常设置在0.04到0.06之间。
-
非极大值抑制和阈值化:对 RR 值进行非极大值抑制,以确保每个局部区域内只保留最强的角点候选。然后,应用一个阈值来确定最终的角点。
-
标记角点:在原始图像上标记出检测到的角点。
实验步骤
- 使用OpenCV读取图像文件'hhl.png'。将图像转换为灰度图,因为角点检测通常在灰度图上进行。
import cv2 img=cv2.imread('hhl.png') #灰度图 gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
- 使用Harris角点检测算法对灰度图进行角点检测。
#Harris角点检测 dst=cv2.cornerHarris(gray,4,3,0.04) #使用Harris角点检测算法对灰度图进行角点检测。 #参数4是邻域大小,3是Sobel算子的孔径大小,0.04是Harris检测器的自由参数。
- 在原图像上标记检测到的角点。
# 标记角点 img[dst>0.05*dst.max()]=[0,0,255] #在原图像上标记检测到的角点。 #这里使用了一个阈值,即如果角点的响应值大于dst数组最大值的5%,则将该点标记为红色。
- 显示处理后的图像。
cv2.imshow('img',img) cv2.waitKey(0)
运行结果
完整代码
import cv2
img=cv2.imread('hhl.png')
#灰度图
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#Harris角点检测
dst=cv2.cornerHarris(gray,4,3,0.04)
# 标记角点
img[dst>0.05*dst.max()]=[0,0,255]
cv2.imshow('img',img)
cv2.waitKey(0)
SIFT(尺度不变特征变换)算法
SIFT(尺度不变特征变换)是一种用于检测和描述局部特征的算法,广泛应用于图像匹配、目标识别、3D重建等领域。SIFT特征对于旋转、尺度缩放、亮度变化具有很好的不变性,因此非常适用于处理现实世界中的图像。
概念
局部特征:局部特征是指图像中那些在小区域内具有独特属性的点,如角点、边缘等。
尺度不变:意味着特征在不同尺度(大小)的图像中都能被检测到。
特征描述符:用于描述关键点周围区域的向量,用于后续的图像匹配。
原理
SIFT算法的实现可以分为以下几个主要步骤:
-
尺度空间极值检测:
- SIFT算法首先使用高斯差分金字塔(DoG金字塔)来检测尺度空间中的极值点。高斯差分金字塔是通过在不同尺度上对图像应用高斯模糊并计算差分得到的。
- 在每个尺度上,算法会比较每个像素与周围像素的亮度差异,以确定该点是否为极值点。
-
关键点定位:
- 对于每个极值点,算法会进行亚像素精确定位,以确定关键点的精确位置。
- 同时,算法还会评估每个关键点的尺度,以确保其尺度不变性。
-
方向赋值:
- 为了使特征具有旋转不变性,SIFT算法为每个关键点分配一个或多个方向。这是通过计算关键点周围区域的海森矩阵的主方向来实现的。
-
关键点描述:
- 算法在关键点周围的16x16像素区域内构建一个方向梯度直方图,以生成关键点的描述符。
- 每个方向直方图分为4个方向,总共有8个方向直方图,每个直方图有4个bins,因此每个关键点的描述符长度为128维。
-
去除低对比度点和边缘点:
- 在构建描述符时,算法会去除低对比度的点和位于边缘附近的点,以增强特征的稳定性。
-
生成特征向量:
- 最后,将所有关键点的描述符组合成一个特征向量,用于后续的图像匹配。
代码步骤
-
读取图像:
- 使用OpenCV的
imread
函数读取名为'man.png'的图像文件。 - 将读取的图像从BGR颜色空间转换为灰度图,因为SIFT算法通常在灰度图上进行。
phone=cv2.imread('man.png') phone_gray=cv2.cvtColor(phone,cv2.COLOR_BGR2GRAY)
- 使用OpenCV的
-
创建SIFT检测器:
- 使用OpenCV的
SIFT_create
函数创建一个SIFT检测器对象。# 创建SIFT检测器 sift=cv2.SIFT_create()
- 使用OpenCV的
-
检测关键点:
- 使用SIFT检测器在灰度图上检测关键点,并将结果存储在变量
kp
中。# 检测关键点 kp=sift.detect(phone_gray)
- 使用SIFT检测器在灰度图上检测关键点,并将结果存储在变量
-
打印关键点坐标:
- 循环遍历检测到的关键点,并打印每个关键点的坐标。
for i in kp: print(i.pt)
- 循环遍历检测到的关键点,并打印每个关键点的坐标。
-
绘制关键点:
- 使用OpenCV的
drawKeypoints
函数在原图像上绘制检测到的关键点。 - 使用OpenCV的
imshow
函数显示绘制了关键点的图像。phone_sift=cv2.drawKeypoints(phone,kp,None,flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS) cv2.imshow('sift',phone_sift) cv2.waitKey(0)
- 使用OpenCV的
-
计算描述符:
- 使用SIFT检测器计算图像中关键点的描述符。
kp,des=sift.compute(phone,kp)
- 使用SIFT检测器计算图像中关键点的描述符。
-
打印关键点和描述符的形状:
- 打印关键点数组和描述符数组的形状。
print(np.array(kp).shape,des.shape)
- 打印关键点数组和描述符数组的形状。
运行结果
完整代码
import cv2
phone=cv2.imread('man.png')
phone_gray=cv2.cvtColor(phone,cv2.COLOR_BGR2GRAY)
# 创建SIFT检测器
sift=cv2.SIFT_create()
# 检测关键点
kp=sift.detect(phone_gray)
for i in kp:
print(i.pt)
# 绘制关键点
phone_sift=cv2.drawKeypoints(phone,kp,None,flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv2.imshow('sift',phone_sift)
cv2.waitKey(0)
# 计算描述符
kp,des=sift.compute(phone,kp)
print(np.array(kp).shape,des.shape)