前言
在车道线检测中,最小二乘法,Hough变换是车道线模型拟合的传统方法之一,通过一系列离散的点拟合出车道直线,也就是得到基于像素平面坐标系的左车道和右车道直线方程。
Hough变换
Hough变换的基本思想
我们先来看看如何表达一条直线,如上图所示,直角坐标系的直线方程为
y
=
a
x
+
b
y=ax+b
y=ax+b,ρ为过原点O作直线的法线距离,θ为法线与水平轴的夹角,因此可以有
x
=
ρ
c
o
s
θ
,
y
=
ρ
s
i
n
θ
x=ρcosθ,y=ρsinθ
x=ρcosθ,y=ρsinθ,因此:
ρ
=
x
c
o
s
θ
+
y
s
i
n
θ
ρ=xcosθ+ysinθ
ρ=xcosθ+ysinθ。这也是直线方程的另一种表示方法,也就是说用ρ和θ两个参数就能表示一条直线,ρ和θ两个数,对应ρ-θ坐标系中的一个点。那么我们也就可以用ρ-θ坐标系中的一个点表示直角坐标系中的一条直线,现在问题在于我们该用什么来表示直角坐标系中的一个点呢?
如上图所示,我们假设直角坐标系有一个点
P
(
x
,
y
)
P(x,y)
P(x,y),已知经过一点可以作无数条直线,我们用这无数条直线的交点来表示这个点。直角坐标系中的一条直线对应于ρ-θ坐标系中的一个点,也就是说直角坐标系的无数条直线对应于ρ-θ坐标系的无数的点,这些点连起来是一条曲线,在Hough空间的曲线方程为
ρ
=
x
c
o
s
θ
+
y
s
i
n
θ
,
x
,
y
ρ=xcosθ+ysinθ,x,y
ρ=xcosθ+ysinθ,x,y为原来直角坐标系的点P的坐标。
结果我们可以看到,平面直角坐标系的一条直线经过Hough变换映射到Hough空间的一个点。平面直角坐标系的一个点经过Hough变换映射到Hough空间的一条曲线。如果直角坐标系的若干个点在同一条直线上,那它们经过Hough变换形成的曲线会交于Hough空间的同一点,而这一点反向变换到直角坐标系中便是直角坐标系的点经过的同一条直线。
而我们实际进行Hough变换时需要进行离散化,由于图像像素是离散的,我们经过一个像素点也不用作无数条直线,而是隔一定角度间隔取一条直线,最后我们变换到Hough空间的也是一个个离散的点。
车道线检测
基本思想
我们对于相机检测图像然后二值化形成的这样一幅二值化图像上每一个白色点
(
x
,
y
),
(x,y),
(x,y),给定一系列离散的θ值(0~360°),可以得到对应的ρ。统计
(
ρ
,
θ
)
(ρ,θ)
(ρ,θ)数值相同的个数,统计计数值较大的点,其对应着待求的直线,而在实际检测统计中我们会求出多条直线,其中包括车道线,我们可以通过一些先验知识适当减小范围来提高检测稳定性。
MATLAB示例
首先我们用imread函数读取图像,语句如下
srcImage = imread('lane.jpg'); %读取图像
imread函数说明
函数原型
Mat imread(const String&filename,int flags=IMREAD_COLOR)
第一个参数 const String&类型的filename,指的是我们需要载入的路径名
第二个参数 int类型的flags,指的是加载的图像颜色类型,默认值为1,也就是彩色。
图像类型flags有以下几种
取值大于0:返回彩色图像
取值为0:返回灰色图像
然后我们需要将图片灰度化。
grayImage = rgb2gray(srcImage); %图片灰度化
rgb2gray是matlab内部一种处理图像的函数,通过消除图像色调和饱和度信息同时保留亮度实现将将RGB图像或彩色图转换为灰度图像,即灰度化处理的功能
然后我们使用medfilt2函数进行中值滤波,滤波和大小为9×9
denoiseImage = medifilt2(grayImage,[9,9]); %中值滤波
再使用sobel算子进行边缘增强
H = fspecial('sobel');
sobelImage = imfilter(denoisedImage,H); %sobel算子边缘增强
再通过最大类间方差法(Otsu)选取阈值(图像阈值也可以理解为灰度图像黑色与白色的界定值),将图像二值化(像素值小于阈值则设置为0,也就是黑色;像素值大于阈值则设置为255,也就是白色)
thresh = graythresh(sobelImage); %选取阈值
binaryImage = imbinarize(sobelImage,thresh); %二值化
然后进行Hough变换就可以得到车道线
[H,theta,rho] = Hough(binaryImage); %Hough变换
p = Houghpeaks(H,5,'threshold',ceil(0.3*max(H(:)))); %获取5个最大值点
lines = Houghlines(binaryImage,theta,rho,p,'FileGap',20,'MinLength',40);
%将这5个Hough空间的点转化为图像的直线段,直线段长度小于40个像素点时就舍弃