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特征则更强大,广泛用于图像匹配与识别任务。


六、参考资料


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

相关推荐
Deepoch2 小时前
Deepoc具身模型开发板:除草机器人的全天候作业中枢
人工智能·科技·机器人·开发板·具身模型·deepoc·除草机器人
灵途科技2 小时前
精密感知赋能具身智能:灵途科技高性能传感器加速机器人多场景落地
人工智能·科技·机器人
冰封剑心2 小时前
容器参数错误,更换参数
人工智能·计算机视觉·vllm
GOWIN革文品牌咨询2 小时前
AI入口下的B2B品牌升级:从内容堆积到标准答案位的重构方法
人工智能·重构·智能设备·工业软件·b2b品牌策划·b2b品牌设计
Shining05962 小时前
推理引擎系列(七)《InfiniLM》
人工智能·深度学习·算法·大模型·ai芯片·智能体·推理引擎
晨非辰2 小时前
Linux终端输出哲学:从回车换行到进度条实战,掌握缓冲区刷新与ANSI控制,告别输出延迟焦虑
linux·运维·服务器·c++·人工智能·后端·自动化
赵孝正2 小时前
Python分块计算(Chunk Processing)详解:解决大规模数据内存溢出的工程实践
数据库·人工智能·python
lpfasd1232 小时前
2026年第12周GitHub趋势周报:Claude生态爆发,AI工程化加速,开发者工具链重构
人工智能·重构·github
无巧不成书02182 小时前
【开源AI视频笔记工具】BiliNote部署教程:本地+Docker双方案,小白也能轻松上手!
人工智能·开源·音视频·bilinote部署教程·cookie获取