1 车道线检测算法设计
一般道路主要由直道和弯道两部分构成,故车道线也相应的分为直车道线和弯曲车道线两种类型,本节首先对道路图像划定感兴趣区以提高运算效率,然后针对两种不同类型的车道线选取不同的检测方法。对于直车道线,利用Hough变换进行直线的提取,筛选并绘制出离车辆最近的两条直车道线;而对于弯曲车道线,则通过最小二乘法利用抛物线模型进行曲线拟合,并根据抛物线二次项系数判别弯道转向。
2 确定感兴趣区
一般车载摄像机采集到的道路图像可划分为天空、路面和周围景物,通过对道路图像进行分析很容易发现车道线主要分布于整个道路图像的下方区域,上方其余区域以及道路区域两侧是天空、树木等非路面区域。为了进一步缩小搜索范围,降低算法复杂度,增强车道线检测的实时性和精确性,应准确进行感兴趣区的定位,故需确定包含车道线等有效信息的区域边界。
3 基于Hough变换的直车道线检测
Hough变换是图像处理中几何特征提取最基本的算法之一,由Paul Hough于1962年提出,后由Richard Duda和Peter Hart于1972年推广使用。Hough变换通过将图像空间的参数映射到参数空间,并结合一种投票算法来检测具有特定形状的物体。Hough变换是目前直线车道检测应用最广的方法之一,鲁棒性好、抗干扰能力强,对断裂或者遮挡的车道线也能够很好的将其检测出来。
4 Hough变换原理
Hough变换的工作原理是利用图像空间的点和参数空间的线之间存在的对偶关系,将图像空间的问题转化到参数空间来解决。
5 Hough 变换的具体实现步骤如下:
(1) 建立一个参数(λ,θ) 空间的二维的数组,该数组相当于一个累加器。
(2) 顺序搜索图像中所有目标(黑色)像素,对于每一个目标像素,在参数空间中根据式(3)找到对应位置,然后在累加器的对应位置加 1。
(3) 求出参数空间(累加器)中最大值,其位置为(λ’,θ’)。
(4) 通过参数空间位置(λ’,θ’) ,根据式(3)找到图像空间中相对应的直线参数。
% 含检测模块的主程序(Otsu阈值分割,矩形感兴趣搜索区域)
close all;
clc;
clear;
tic;%程序执行的起始时间
k=1;
% mri=uint8(zeros(128,160,3,120));%建立4维的矩阵,前面的两维不管,由后面两维决定
% T,n为检测模块判断标志
T=0;
n=0;
a=0;
for frame=1:100
T=T+1;%%%%%%用于记录第几帧图像
startNum=frame;
imStr=num2str(startNum);
%imName=strcat('1000_',imStr,'.bmp');%以上几句实现字符串连接的操作
imName=strcat('E:\DCIM\shipinchuli\shipinchuli2\m',imStr,'.jpg');%以上几句实现字符串连接的操作
orig=imread(imName);%读取图片
origGray = rgb2gray(orig);%图片灰度化
mylane=origGray;
[height,width] = size(origGray);
figure,imshow(origGray),title('origGray');%显示灰度图片
%%%%%%水平平均灰度投影
% grayProject=areaskybar(origGray,width,height);
% figure,barh(grayProject,0.5); %绘制二维水平条形图
%%%%%%白线Otsu阈值分割,得到图像segmentorig
OtsuGray=origGray;
[threshOtsu,segmentorig]=autothresh(OtsuGray,height,width);%大津法阈值分割函数 返回最佳阈值和部分图像块 暂时好像没用着
% figure,imshow(segmentorig),title('segmentorig');
%
% imhist(origGray); %绘制灰度直方图
% [counts,x]=imhist(origGray);
% orighictr=histeq(origGray); %增强对比度
% figure,imshow(orighictr),imshow('orighictr');
%%%%%边缘二值图像,sobel算子
[origEdgeBw,sobthresh]= edge(origGray,'sobel','vertical'); % B、Bw表示二值化 用Sobel边缘检测算子进行边缘检测 返回二值图像和阈值
%origEdgeBw 产生一个掩膜矩阵
%sobthresh 阈值
% [origEdgeBw,sobthresh]= edge(origGray,'sobel');
% origEdgeBw=sobell(height,width,origGray);%自己编的sobel算子函数
% figure,imshow(origEdgeBw),title('edgedIm');
%边缘灰度图像
edgedIm = double(origGray).*double(origEdgeBw);%通过掩膜矩阵与原图像相乘,类似于与运算
% figure,imshow(edgedIm),title('edgedIm');
laneDispF = floor( MyFilt(edgedIm,100) ); % 滤波 感觉没变化
% figure,imshow(laneDispF),title('laneDisp');
% figure;
% segorigF=floor(MyFilt(segmentorig,100));%滤波
% figure,imshow(segorigF),title('segorig Filt');
skyline=areasky(origGray,width,height); %求陆天分界线 第一幅图:79行
if T==1 %第一幅图像用检测模块进行检测,后面的图像用跟踪实现
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 调用检测模块%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[lData,rData,lReservedPnt,rReservedPnt,Detorig]=detect(orig,origGray,laneDispF,segmentorig,imName);
% lData,rData为左右拟和直线上间隔取点的坐标数组
Imrsize=imresize(Detorig,2);%变为Detorig的2倍
mri(:,:,:,k)=Imrsize;
k=k+1;
else
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 进入跟踪阶段%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 从记录的边界点附近寻找当前的边界点
% 左边界
subL = 0;
for t = 1:lReservedPnt
for temp = lData(t,1)-10 : lData(t,1)+10 % 在左右各10个象素内搜索特征点
if( temp>0 && temp<=width && segmentorig(height-lData(t,2),temp) ~= 0 )
subL = subL + 1;
leftLanePnts(subL,1) = temp;
leftLanePnts(subL,2) = lData(t,2);
break;
end
end
end
% 右边界
subR = 0;
for t = 1:rReservedPnt
for temp = rData(t,1)-10 : rData(t,1)+10
if( temp>0 && temp<=width && laneDispF(height-rData(t,2),temp) ~= 0 )
subR = subR + 1;
rightLanePnts(subR,1) = temp;
rightLanePnts(subR,2) = rData(t,2);
break;
end
end
end
完整代码或者代写添加QQ1575304183