前言
在学习车道线检测相关,从最基础的图像处理开始
遇到的第一个算法是霍夫变换Hough Transform
故写下此文记录自己对于霍夫变换的理解
定义
霍夫变换用于检测简单的直线、曲线
以车道线检测为例子,经过灰度处理、滤波、边缘检测处理后得到下图
如何在有噪点、断点的条件下,找到红色的线,这就是霍夫变换所作的工作
一种直观的思想就是遍历所有直线,找到经过点最多的直线
但是如果用常规的
y
=
k
x
+
b
y=kx+b
y=kx+b,那么不得不面临的问题是在
y
y
y趋向垂直时,
k
k
k趋向无限大
显然这时极其占用运算资源的,因此Duda 和 Hart提出使用Hesse normal form来表示直线的参数:
r
=
x
c
o
s
(
θ
)
+
y
s
i
n
(
θ
)
r= xcos(\theta)+ysin(\theta)
r=xcos(θ)+ysin(θ)
r
r
r是从原点到直线的距离,
θ
\theta
θ是
r
⃗
\vec {r}
r和
x
x
x轴的夹角
如下图所示,黄色、绿色、红色的线都是过点
(
x
0
,
y
0
)
(x_0,y_0)
(x0,y0)的直线
过坐标原点对直线作垂线,与之相交得到的垂足,就是公式
r
=
x
0
c
o
s
(
θ
)
+
y
0
s
i
n
(
θ
)
r= x_0cos(\theta)+y_0sin(\theta)
r=x0cos(θ)+y0sin(θ)所包含的
r
r
r和
θ
\theta
θ
即霍夫变换把每一条线转换成一个关于
r
r
r和
θ
\theta
θ的点
这个表达式的数学来源如下:
y
0
=
−
c
o
s
(
θ
)
s
i
n
(
θ
)
x
0
+
r
s
i
n
(
θ
)
y_0=-\frac{cos(\theta)}{sin(\theta)}x_0+\frac{r}{sin(\theta)}
y0=−sin(θ)cos(θ)x0+sin(θ)r
所以
r
=
x
c
o
s
(
θ
)
+
y
s
i
n
(
θ
)
r= xcos(\theta)+ysin(\theta)
r=xcos(θ)+ysin(θ)
在这样的情况下,如何表示点的共线呢?
在下图中,我们计算了三个点各自的直线的参数
可以发现,在60°处的支撑线都具有相似的长度r
即对应的线(下图中的蓝色)非常相似,可以假定所有点都位于蓝线附近,蓝线就是我们需要的线
即需要各个点的经过的直线
r
r
r和
θ
\theta
θ的参数非常相近
这些
r
r
r和
θ
\theta
θ单独画出来,就是下图所示的正弦曲线
因为
r
=
x
0
c
o
s
(
θ
)
+
y
0
s
i
n
(
θ
)
=
x
0
2
+
y
0
2
s
i
n
(
θ
+
φ
)
r= x_0cos(\theta)+y_0sin(\theta)=\sqrt{x_0^2+y_0^2}sin(\theta+\varphi)
r=x0cos(θ)+y0sin(θ)=x02+y02sin(θ+φ)
蓝色、橙色、绿色分别是经过
(
8
,
6
)
(8,6)
(8,6),
(
4
,
9
)
(4,9)
(4,9),
(
12
,
3
)
(12,3)
(12,3)点所有直线的
r
r
r和
θ
\theta
θ的参数集合
他们的交点是
(
9.6
,
0.925
)
(9.6,0.925)
(9.6,0.925)(
r
r
r和
θ
\theta
θ参数下)
我们知道曲线上的任意一点代表一条过
(
x
0
,
y
0
)
(x_0,y_0)
(x0,y0)的直线,那么交点代表的,是经过
(
8
,
6
)
(8,6)
(8,6),
(
4
,
9
)
(4,9)
(4,9),
(
12
,
3
)
(12,3)
(12,3)这三个点的直线,也就是我们需要找的直线
作出垂直于
(
0
,
0
)
(0,0)
(0,0)和
(
9.6
c
o
s
(
0.925
)
,
9.6
s
i
n
(
0.925
)
)
(9.6cos(0.925),9.6sin(0.925))
(9.6cos(0.925),9.6sin(0.925))直线的线
得到我们需要的红色的线,可以发现确实是经过三个点的直线
一些其他的发现
将
r
r
r和
θ
\theta
θ的参数集合,即曲线,映射到笛卡尔坐标系下,即所有垂足的集合是一个圆
这很好理解,毕竟在极坐标系下
ρ
=
s
i
n
(
θ
)
\rho=sin(\theta)
ρ=sin(θ)表示的是圆
根据定义就知道每一个点所表达的直线就是该点的切线
致谢
Hough Transform的论文
Hough Transform的wiki
OpenCV的Hough Transform文档