OpenCV计算机视觉实战(17)——特征点检测详解
0. 前言
在计算机视觉中,角点 (Corner
, 也称特征点) 是图像中特征信息最丰富的点,对应周围像素灰度在两个正交方向均有显著变化。准确检测并定位角点,对于后续的图像配准、运动跟踪和三维重建等任务至关重要。本文将介绍并实现经典的 Harris
角点检测、改进的 Shi-Tomasi
算法以及亚像素级角点优化。
1. Harris 角点检测
Harris
算法基于自相关矩阵,对图像每个像素邻域的灰度变化进行二阶矩分析,当两个正交方向都发生大变化时,该像素即为角点。
1.1 应用场景
- 摄像头标定:角点分布均匀、特征明显,便于内参求解
- 纹理分析:建筑、机械表面角点多,能辅助表面缺陷检测
- 目标跟踪:对比边缘,角点更易在变形、遮挡下保持稳定
1.2 实现过程
- 读取图像并灰度化
- 计算图像梯度:使用
Sobel
算子分别获取 I x I_x Ix, I y I_y Iy - 构建自相关矩阵
M = ( ∑ w I x 2 ∑ w I x I y ∑ w I x I y ∑ w I y 2 ) M= \begin{pmatrix}∑w I_x^2&∑w I_xI_y\\ ∑w I_xI_y&∑w I_y^2 \end{pmatrix} M=(∑w Ix2∑w IxIy∑w IxIy∑w Iy2)
其中 w w w 是高斯窗口 - 计算响应函数
R = d e t ( M ) − k ( t r a c e ( M ) ) 2 R=det(M)−k (trace(M))^2 R=det(M)−k (trace(M))2
k k k 常取0.04–0.06
- 非极大值抑制与阈值筛选:保留局部最大且 R R R 大于阈值的点
import cv2
import numpy as np
# 功能:Harris 角点检测并可视化
img = cv2.imread('1.jpeg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = np.float32(gray)
# 1. 直接调用 OpenCV Harris
dst = cv2.cornerHarris(src=gray, blockSize=2, ksize=3, k=0.06)
# 2. 扩大标记区域并阈值化
dst = cv2.dilate(dst, None)
corners = dst > 0.01 * dst.max()
# 3. 在原图中标记角点
output = img.copy()
output[corners] = [0, 0, 255]
cv2.imshow('Harris Corners', output)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.cornerHarris(src, blockSize, ksize, k)
:blockSize
:角点检测时考察邻域大小ksize
:Sobel
求导算子大小k
:Harris
参数,控制响应函数的敏感度
cv2.dilate(src, kernel)
:对检测响应图进行膨胀,便于后续非极大值检测- 阈值筛选 (
dst > thresh
):保留响应值较大的角点
2. Shi-Tomasi 算法
Shi-Tomasi
算法在 Harris
基础上,使用自相关矩阵的最小特征值 λ m i n λ_{min} λmin 作为角点响应,更稳定、无需调参 k k k。
2.1 应用场景
- 移动目标跟踪:
Shi-Tomasi
的最小特征值度量更稳定,常用作金字塔光流跟踪的初始化点 - 机器人导航:室内房间角落、门框角点分布稀疏,用少量高质量特征即可定位
- 图像拼接:特征点质量与分布影响拼接精度,
Shi-Tomasi
质量水平可控制点的可靠性
2.2 实现过程
- 读取与灰度化
- 直接调用
goodFeaturesToTrack
,传入最大角点数、质量水平、最小距离等参数 - 可选:在每个角点处绘制圆圈以便可视化
import cv2
import numpy as np
# 功能:Shi-Tomasi 角点检测并可视化
img = cv2.imread('1.jpeg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 1. 调用 OpenCV Shi-Tomasi
corners = cv2.goodFeaturesToTrack(
image=gray,
maxCorners=200,
qualityLevel=0.01,
minDistance=10,
blockSize=3
)
corners = np.int0(corners)
# 2. 可视化
output = img.copy()
for x, y in corners.reshape(-1, 2):
cv2.circle(output, (x, y), 4, (0, 255, 0), -1)
cv2.imshow('Shi-Tomasi Corners', output)
cv2.waitKey(0)
cv2.destroyAllWindows()
关键函数解析:
cv2.goodFeaturesToTrack(image, maxCorners, qualityLevel, minDistance, blockSize)
:maxCorners
:返回角点的最大数量qualityLevel
:角点质量阈值,相当于最小 λ m i n / λ m a x λ_{min}/λ_{max} λmin/λmaxminDistance
:角点之间的最小欧氏距离blockSize
:计算自相关矩阵的邻域大小
3. 亚像素级角点
在图像金字塔与光流等任务中,亚像素级别的角点位置能显著提升跟踪与配准精度。通过 cornerSubPix
方法,利用灰度图在小窗口内对角点坐标做迭代优化。
3.1 应用场景
- 立体匹配:亚像素精度可显著提升深度图分辨率
- 显微镜图像:细胞或晶体内微小角点需精确定位
- 机械误差测量:高精度角点抠图,辅助工业检测与校准
3.2 实现过程
- 先用
Shi-Tomasi
得到粗略角点 - 定义搜索窗口大小与终止条件
- 调用
cornerSubPix
,传入灰度图、初始角点、窗口大小与停止迭代条件 - 查看亚像素精度坐标
import cv2
import numpy as np
# 功能:Shi-Tomasi + 亚像素角点优化
img = cv2.imread('1.jpeg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 1. 原始角点
corners = cv2.goodFeaturesToTrack(gray, 100, 0.01, 10)
corners = np.float32(corners)
# 2. 设置优化参数
winSize = (5, 5)
zeroZone = (-1, -1)
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 40, 0.001)
# 3. 亚像素优化
corners_refined = cv2.cornerSubPix(
image=gray,
corners=corners,
winSize=winSize,
zeroZone=zeroZone,
criteria=criteria
)
# 4. 可视化
output = img.copy()
for x, y in corners_refined.reshape(-1, 2):
cv2.circle(output, (int(x), int(y)), 3, (255, 0, 0), -1)
cv2.imshow('Subpixel Corners', output)
cv2.waitKey(0)
cv2.destroyAllWindows()
关键函数解析:
cv2.cornerSubPix(image, corners, winSize, zeroZone, criteria)
:corners
:输入初始角点位置winSize
:搜索窗口大小zeroZone
:窗口中不参与计算的中心区域criteria
:迭代终止条件,组合了最大迭代次数与精度阈值
小结
角点作为图像中信息密度最高的特征点,在计算机视觉任务中扮演着至关重要的角色。本文介绍了三种常用的角点检测方法:Harris
算法以响应函数衡量角点强度,适合特征丰富场景;Shi-Tomasi
算法通过最小特征值选择更稳定的角点,更适用于后续跟踪与匹配;而亚像素角点优化则进一步提升了检测精度,满足高精度应用需求。
系列链接
OpenCV计算机视觉实战(1)——计算机视觉简介
OpenCV计算机视觉实战(2)——环境搭建与OpenCV简介
OpenCV计算机视觉实战(3)——计算机图像处理基础
OpenCV计算机视觉实战(4)——计算机视觉核心技术全解析
OpenCV计算机视觉实战(5)——图像基础操作全解析
OpenCV计算机视觉实战(6)——经典计算机视觉算法
OpenCV计算机视觉实战(7)——色彩空间详解
OpenCV计算机视觉实战(8)——图像滤波详解
OpenCV计算机视觉实战(9)——阈值化技术详解
OpenCV计算机视觉实战(10)——形态学操作详解
OpenCV计算机视觉实战(11)——边缘检测详解
OpenCV计算机视觉实战(12)——图像金字塔与特征缩放
OpenCV计算机视觉实战(13)——轮廓检测详解
OpenCV计算机视觉实战(14)——直方图均衡化
OpenCV计算机视觉实战(15)——霍夫变换详解
OpenCV计算机视觉实战(16)——图像分割技术