OpenCV图像特征提取:Harris角点检测与SIFT特征提取实战

前言

在计算机视觉领域,角点检测特征提取是图像识别、目标跟踪、图像拼接等任务的基础。本文将使用OpenCV实现经典的Harris角点检测算法和SIFT(尺度不变特征变换)特征提取算法,并通过代码演示关键步骤,帮助读者快速上手。


一、环境配置

  • Python 3.x

  • OpenCV contrib(支持SIFT)

  • NumPy


二、Harris角点检测

1. 什么是角点?

角点是图像中局部区域与周围区域灰度变化剧烈的点,例如物体的拐角、边缘交点。Harris角点检测通过计算像素点在各个方向上的灰度变化来判定是否为角点,具有旋转不变性,但对尺度变化敏感。

2. 核心函数

复制代码
dst = cv2.cornerHarris(src, blockSize, ksize, k)
参数 说明
src 输入图像,必须是单通道灰度图(float32类型最佳)
blockSize 角点检测时邻域窗口大小(整数,如2、3、5),窗口越大检测越宏观
ksize Sobel算子的卷积核大小(必须是奇数:3、5、7),用于计算图像梯度
k Harris角点检测的自由参数,经验值范围0.04~0.06

返回值dst是一个与输入图像同尺寸的浮点型数组,每个元素表示对应像素点的角点响应值,值越大,该点是角点的概率越高。

3. 代码实现

复制代码
import cv2
import numpy as np

# 读取图像并调整尺寸
img = cv2.imread("cxk.jpg")
img = cv2.resize(img, (400, 500))

# 转为灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Harris角点检测
dst = cv2.cornerHarris(gray, blockSize=4, ksize=3, k=0.04)

# 标记检测到的角点(阈值处理)
img[dst > 0.05 * dst.max()] = [0, 0, 255]   # 将角点标记为红色

cv2.imshow("Harris角点检测", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

代码说明

  • 将彩色图转换为灰度图,减少计算量。

  • 调用cornerHarris进行角点检测,得到响应图dst

  • 使用0.05 * dst.max()作为阈值,将响应值大于该阈值的像素点设为红色,即标记为角点。

运行结果:原图中的角点被红色像素标记,效果如下图所示(示例):


三、SIFT特征提取

1. 什么是SIFT?

SIFT(Scale-Invariant Feature Transform,尺度不变特征变换)是一种检测图像局部特征的算法。它提取的特征对旋转、尺度缩放、亮度变化保持不变性,非常稳定,广泛应用于图像匹配、物体识别等领域。

2. SIFT主要步骤

  1. 尺度空间极值检测:通过高斯差分金字塔寻找候选关键点。

  2. 关键点精确定位:剔除低对比度点和边缘响应点。

  3. 方向赋值:为每个关键点计算主方向,保证旋转不变性。

  4. 关键点描述:生成128维特征向量,用于后续匹配。

3. 核心函数

  • cv2.SIFT_create():创建SIFT对象。

  • sift.detect(img):检测关键点。

  • sift.compute(img, kp):计算关键点描述符。

  • sift.detectAndCompute(img, mask):一步完成检测和计算。

4. 代码实现

复制代码
man = cv2.imread("cxk.jpg")
man = cv2.resize(man, (400, 500))
man_gray = cv2.cvtColor(man, cv2.COLOR_BGR2GRAY)

# 创建SIFT对象
sift = cv2.SIFT_create()

# 检测关键点
kp = sift.detect(man_gray, None)

# 绘制关键点(显示大小和方向)
man_sift = cv2.drawKeypoints(man, kp, None,
                             flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv2.imshow("SIFT关键点", man_sift)
cv2.waitKey(0)

# 计算描述符
kp, des = sift.compute(man, kp)
print("关键点数量:", np.array(kp).shape)
print("描述符形状:", des.shape)   # 输出 (N, 128)

cv2.destroyAllWindows()

代码说明

  • sift.detect()返回关键点列表kp,每个关键点包含坐标pt、尺度size、方向angle等属性。

  • cv2.drawKeypointsflags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS会绘制出关键点的圆形区域和方向线,直观展示特征点的尺度和方向。

  • sift.compute()计算描述符,输出des是一个二维数组,形状为(关键点数量, 128),每个128维向量用于唯一描述该关键点。

运行结果

  • 图像上会显示关键点位置及其圆形区域和方向线。

  • 控制台输出类似:

    复制代码
    关键点数量: (391,)
    描述符形状: (391, 128)

四、SIFT的实际应用:特征匹配(扩展)

SIFT描述符常用于图像匹配。下面是一个简单的特征匹配示例,展示如何将两幅图像的特征点进行匹配:

复制代码
# 读取两张图像
img1 = cv2.imread("scene.jpg")
img2 = cv2.imread("object.jpg")

sift = cv2.SIFT_create()
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)

# 创建FLANN匹配器
flann = cv2.FlannBasedMatcher()
matches = flann.knnMatch(des1, des2, k=2)

# 应用比率测试筛选良好匹配
good = []
for m, n in matches:
    if m.distance < 0.75 * n.distance:
        good.append(m)

# 绘制匹配结果
result = cv2.drawMatches(img1, kp1, img2, kp2, good, None, flags=2)
cv2.imshow("SIFT匹配", result)
cv2.waitKey(0)

通过匹配点对的数量或距离阈值,可以实现图像识别、指纹验证等任务。


五、总结

方法 作用 特点
Harris角点检测 检测图像中的角点 旋转不变,但对尺度变化敏感
SIFT特征提取 检测关键点并生成描述符 尺度、旋转、光照不变,适合匹配

通过本文的学习,你已经掌握了OpenCV中两种经典特征提取方法的基本使用。Harris角点检测适合快速定位图像中的角点区域,而SIFT特征则更强大,广泛用于图像匹配与识别任务。


六、参考资料


如果本文对你有帮助,请点赞、收藏、评论支持一下,你的鼓励是我持续创作的动力!

相关推荐
冬奇Lab13 分钟前
RAG 系列(十三):查询优化——让问题问得更好
人工智能·llm
上海云盾第一敬业销售16 分钟前
大模型驱动的网络攻击:AI对抗AI,智能WAF的进化之路
人工智能
冬奇Lab17 分钟前
企业引入 AI 之后,为什么提效不明显?
人工智能·aigc
冬奇Lab34 分钟前
一天一个开源项目(第98篇):UI-TARS-Desktop - 字节跳动开源的多模态 GUI 代理栈
人工智能·开源·资讯
青岛前景互联信息技术有限公司42 分钟前
OpenClaw 重构智慧消防:AI时代的平台融合实践
大数据·人工智能
梦梦代码精1 小时前
BuildingAI 上部署自定义工作流智能体:5 个实用技巧
大数据·人工智能·算法·开源软件
极客老王说Agent1 小时前
2026智造前瞻:实在Agent生产排期智能助理核心功能与使用方法详解
大数据·人工智能·ai·chatgpt
Mr_pyx1 小时前
Spring AI 入门教程:Java开发者的AI应用捷径
java·人工智能·spring
巫山老妖2 小时前
鹅厂十年:三段式技术成长复盘
android·人工智能·程序员