OpenCV之霍夫变换
霍夫变换(Hough Transform)是一种经典的形状检测算法,尤其在直线、圆等几何图形识别中应用广泛。它通过将图像空间中的特征映射到参数空间进行投票,最终找到最匹配的几何形状。以下从原理到实战的全面解析:
一、霍夫变换的核心思想
1. 图像空间 → 参数空间
- 问题:在图像中直接检测直线(或圆)困难,因为噪声、断裂会影响结果。
- 解决方案:将检测问题转换为参数空间的峰值搜索问题。
2. 以直线检测为例
- 图像空间:一条直线由无数像素点组成。
- 参数空间(霍夫空间):直线表示为
(ρ, θ)
极坐标参数:ρ
:直线到原点的垂直距离θ
:直线的法线与x轴的夹角
3. 投票机制
- 图像中每个边缘点对应参数空间的一条曲线,多条曲线的交点即为潜在的直线参数。
二、霍夫直线检测(从像素到参数)
1、霍夫直线检测流程
-
对每个边缘点
(x,y)
:- 穷举所有可能的θ(例如
0°, 1°, ..., 180°
) - 对每个θ,计算对应的ρ:
ρ = x·cosθ + y·sinθ
- 将结果
(θ, ρ)
记录到投票表(累加器)
- 穷举所有可能的θ(例如
-
统计投票结果:
- 所有点计算完成后,投票数最多的
(θ, ρ)
组合即为图像中的直线。
- 所有点计算完成后,投票数最多的
-
阈值筛选:
- 仅保留投票数超过阈值的组合(排除噪声干扰)。
2、霍夫直线检测案例
输入图像 (5x5 像素)
假设有一张微型二值图像,白色(255)为边缘点,黑色(0)为背景:
import numpy as np
image = np.array([[0, 0, 255, 0, 0],[0, 255, 0, 255, 0],[255, 0, 0, 0, 255],[0, 255, 0, 255, 0],[0, 0, 255, 0, 0]
], dtype=np.uint8)
这个图像是一个X形交叉的直线,我们手动模拟霍夫变换检测过程。
步骤1:提取边缘点坐标
找到所有白色像素的位置(边缘点):
(0,2),
(1,1), (1,3),
(2,0), (2,4),
(3,1), (3,3),
(4,2)
步骤2:定义参数空间
- 直线参数:使用极坐标
(ρ, θ)
ρ
(rho):直线到原点的垂直距离(范围:-max_dist
到max_dist
,这里max_dist=√(4²+4²)≈5
)θ
(theta):角度(范围:0~180°
,按步长45°
简化计算)
步骤3:为每个边缘点投票
对每个边缘点 (x,y)
,计算所有可能的 (ρ, θ)
:
- 公式:
ρ = x*cosθ + y*sinθ
- 示例1:点 (2,0)
- θ=0°: ρ = 2cos0 + 0sin0 = 2
- θ=45°: ρ = 2cos45 + 0sin45 ≈ 1.41
- θ=90°: ρ = 2cos90 + 0sin90 = 0
- θ=135°: ρ = 2cos135 + 0sin135 ≈ -1.41
将计算结果填入累加器(投票表):
θ \ ρ | -2 | -1 | 0 | 1 | 2 |
---|---|---|---|---|---|
0° | +1 | ||||
45° | +1 | ||||
90° | +1 | ||||
135° | +1 |
- 重复所有点的计算:
- 点
(0,2)
→ 在θ=90°
时ρ=2
(投票) - 点
(4,2)
→ 在θ=90°
时ρ=4
(超出范围忽略)
- 点
最终累加器(部分):
θ \ ρ | -2 | -1 | 0 | 1 | 2 |
---|---|---|---|---|---|
0° |