一、角点检测

1. 什么是角点检测

角点检测(Corner Detection) 是计算机视觉中的一种基础特征提取方法,用于识别图像中具有显著灰度变化的像素点,即角点(Corner)。

角点是图像中在不同方向上灰度值均发生剧烈变化的点,例如:

  • 物体的尖角
  • 两条边的交点
  • T形或L形结构的端点

角点具有以下优良特性:

  • 旋转不变性:图像旋转后角点仍然可被检测
  • 尺度不变性:在不同缩放比例下角点依然存在
  • 光照不变性:对光照变化具有一定的鲁棒性

在这里插入图片描述

2. 检测流程

角点检测通常遵循以下流程:

步骤 描述
1. 输入图像 加载待检测的原始图像
2. 图像预处理 灰度化、降噪等,为后续处理做准备
3. 特征提取 使用Harris、Shi-Tomasi等算法提取角点特征
4. 角点响应计算 计算每个像素点的角点响应值
5. 角点定位与标记 根据响应值定位角点并可视化标记
6. 后处理(可选) 非极大值抑制、阈值过滤等
7. 输出结果 返回角点坐标或标记后的图像

在这里插入图片描述

3. 邻域(Neighborhood)

在角点检测中,邻域是指以某个中心像素为核心,周围一定范围内的像素集合。邻域内的像素信息用于计算中心像素的角点响应值。

邻域大小对检测结果有重要影响:

邻域大小 特点
较大邻域 捕获更多细节信息,但计算量增加
较小邻域 计算速度快,但可能遗漏细微特征

邻域的尺寸通常由 blockSize 参数控制,需要根据具体的应用场景和图像特征进行调整。

在这里插入图片描述

4. Harris 角点检测案例

Harris 角点检测是一种经典的角点检测算法,其核心思想是利用图像梯度计算角点响应值。

关键函数说明

cv2.cornerHarris(img, blockSize, ksize, k, dst=None)
参数 说明
img 输入图像(需为灰度图)
blockSize 角点检测中考虑的邻域大小
ksize Sobel 算子窗口大小(用于计算梯度)
k Harris 自由参数,取值范围 [0.04, 0.06]
dst 输出响应矩阵(与输入图像尺寸相同)

完整代码

import cv2

# 加载图像
img = cv2.imread('huanghelou.png')
cv2.imshow('原始图像', img)
cv2.waitKey(0)

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

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

# 标记角点(响应值大于阈值的像素标记为绿色)
threshold = 0.05 * dst.max()
img[dst > threshold] = [0, 255, 0]

# 显示结果
cv2.imshow('角点检测结果', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

代码解析

  • gray 输入图像必须为灰度图

  • blockSize=4 表示邻域尺寸为 4×4

  • ksize=3 表示 Sobel 算子的孔径大小为 3

  • k=0.04 为 Harris 自由参数,值越小检测到的角点越多

  • dst 矩阵中值越大的像素,是角点的概率越高

  • 通过阈值 0.05 * dst.max() 筛选角点

在这里插入图片描述

二、SIFT 特征提取

1. 什么是 SIFT

SIFT(Scale-Invariant Feature Transform,尺度不变特征变换) 是一种用于检测和描述图像局部特征的经典算法。

SIFT 能够在尺度空间中寻找极值点,并提取出具有以下特性的关键点:

尺度不变性:对图像缩放具有鲁棒性

旋转不变性:对图像旋转具有鲁棒性

光照不变性:对光照变化具有一定的容忍度

SIFT 提取的特征点可以用于图像匹配、目标识别、三维重建等多种任务。

2. 特征提取的一般步骤

步骤 描述
1. 数据预处理 去噪、归一化、平滑等
2. 特征选择 选择合适的特征子集,避免冗余和噪声
3. 特征提取 使用数学算法计算和提取特征
4. 特征表示 将特征表示为向量或其他便于计算的形式

好的特征应具备:

辨别性:能够区分不同类别或实例

鲁棒性:对变形和噪声有一定容忍度

3. SIFT 案例实现

完整代码

import cv2
import numpy as np

# 加载图像
man = cv2.imread('man.png')
cv2.imshow('原始图像', man)
cv2.waitKey(0)

# 灰度转换
man_gray = cv2.cvtColor(man, cv2.COLOR_BGR2GRAY)

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

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

# 打印所有关键点坐标
for point in kp:
    print(f'关键点坐标: {point.pt}')

# 绘制关键点(显示尺度和方向)
man_sift = cv2.drawKeypoints(
    man,
    kp,
    None,
    flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS
)

cv2.imshow('SIFT 关键点', man_sift)
cv2.waitKey(0)

# 计算关键点描述符(用于后续匹配)
keypoints, descriptors = sift.compute(man, kp)

print(f'关键点数量: {np.array(keypoints).shape[0]}')
print(f'描述符矩阵形状: {descriptors.shape}')
print('描述符维度: 128 维')

cv2.destroyAllWindows()

代码解析

方法 说明
cv2.SIFT_create() 创建 SIFT 检测器对象
sift.detect(gray) 检测图像中的关键点,返回关键点列表
sift.compute(img, kp) 计算关键点的描述符(128维向量)
cv2.drawKeypoints() 在图像上绘制关键点

关键点信息

每个关键点包含:坐标 (x, y)、尺度、方向

每个关键点的描述符为 128 维向量

描述符可用于后续的特征匹配(如 FLANN、BFMatcher)

在这里插入图片描述

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐