【图像检测】基于Hough变换算法检测视频车道线检测matlab代码

1 简介

随着全球经济的快速发展,居民的车辆拥有率也在不断攀升,伴随而来的就是日益严重的交通问题。为了减缓交通运输压力,世界各国都加强了对智能交通系统的研究和建设。交通运输未来的发展趋向于智能化,作为一种新兴产业,智能交通已为我国经济不断发展注入了新的动力。车道偏离预警系统作为 ITS其中的一部分,在车辆偏离车道行驶时,通过发出警告提醒驾驶人员进而避免危险发生。而构成交通环境的基础因素就是车道线,因此车道线的检测尤为重要。本文主要基于 Hough(霍夫)变换原理,以交通视频检测图像为研究对象,对车道检测的关键技术进行了研究。Hough变换作为一种常用的从图像中识别出几何图形的方法,其具有较好鲁棒性,可以在噪声环境比较大的情况下识别出车道直线。  首先,本文大概介绍了智能交通系统及车道预警系统的应用需求,国内外对其的研究及应用现状。针对图像的预处理问题,本文对图像灰度化、灰度的线性变换、图像增强及边缘检测进行了分析与实现,以采集到的车道图像作为实验对象,通过对比实际效果确定了车道预处理的具体流程与方法。通过分析几种交通检测方法及常用车道检测方法,并对 Hough变换进行了测试,通过比较实际效果,充分说明了 Hough变换在车道检测方面的优越性,最终确定将 Hough变换作为主要算法。然后以交通监测视频中提取的背景图像为研究对象,针对车道划分对车道背景主要进行了以下处理:首先将背景车道进行灰度处理,将彩色图片转换为灰度图;其次是将处理后的灰度图进行灰度线性变化和二值化处理,目的是去除车道边缘附近的噪声白点;将生成的二值图进行中值滤波和Roberts边缘检测,然后进行Hough变换拟合出车道线​

2 部分代码

function colorAndTypeIdx = videodetectcolorandtype(twoLines_0b, YCbCr)  
% VIDEODETECTCOLORANDTYPE - Detects if the lane detected is Yellow/White
% and Solid/Broken in videoldws demo.

%   Copyright 2008-2009 The MathWorks, Inc.

% twoLines_0b = coordinate points of lines (0 based) 
%
% Here, for a line with start point (r1,c1) and end point (r2,c2),
% we form a ROI with points: 
% (r1,c1-HALF_OFFSET) (r1,c1+HALF_OFFSET) 
% (r2,c2-HALF_OFFSET) (r2,c2+HALF_OFFSET) 
% We search for yellow/white color within this ROI 

INVALID_COLOR = int8(0);
WHITE_COLOR   = int8(1);
YELLOW_COLOR = int8(2); 

INVALID_MARKING = int8(0);
BROKEN_MARKING = int8(1); 
SOLID_MARKING   = int8(2);

INVALID_COLOR_OR_TYPE = int8(1);% color=yellow/white; type=broken or solid
YELLOW_BROKEN = int8(2); 
YELLOW_SOLID   = int8(3); 
WHITE_BROKEN   = int8(4); 
WHITE_SOLID   = int8(5); 

lineColorIdx   = int8([0 0]);
solidBrokenIdx = int8([0 0]);
colorAndTypeIdx = int8([0 0]);
HALF_OFFSET =  int32(10);

zeroI32 = int32(0);
oneI32 = int32(1);
twoI32 = int32(2);

rH = int32(size(YCbCr(:,:,1),1));
cW = int32(size(YCbCr(:,:,1),2));

tmpInImage_Y = YCbCr(:,:,1);
tmpInImage_Cb = YCbCr(:,:,2);

leftC = int32(zeros(rH,1));
rightC = int32(zeros(rH,1));
Rs     = int32(zeros(rH,1));

twoLines_1b = twoLines_0b([2 1 4 3], :);
for i=oneI32:int32(length(twoLines_1b(:)))
   twoLines_1b(i) = twoLines_1b(i) + oneI32;
end

for lineIdx =oneI32:twoI32%1:2
   %% one line
   r1c1r2c2 = twoLines_1b(:,lineIdx) - 1;
   r1 = r1c1r2c2(1); 
   c1 = r1c1r2c2(2); 
   r2 = r1c1r2c2(3); 
   c2 = r1c1r2c2(4); 

   % make sure r1 is the min (r1,r2)
   if r1>r2
       tmp=r2;
       r2=r1;
       r1=tmp;

       tmp=c2;
       c2=c1;
       c1=tmp;   
   end

   pointNotLine = (r1==r2) && (c1==c2);
   
   % find if line is within image: (r1,c1) and (r2,c2) must be within image
   if ((r1>zeroI32 && r1 <= rH) && (c1>zeroI32 && c1 <= cW) && ...
      (r2>zeroI32 && r2 <= rH) && (c2>zeroI32 && c2 <= cW)) && ~pointNotLine
       line_within_image = logical(true);
   else
       line_within_image = logical(false);
   end

   if (line_within_image)
       len = r2-r1+oneI32;
       i=oneI32;
       % Rs(1:len)=r1:r2
       for p=r1:r2
         Rs(i) = p;
         i=i+oneI32;
       end
       %leftC(1:len) = int32(linspace(c1-HALF_OFFSET, c2-HALF_OFFSET, len));
       %y = linspace(d1, d2, n)
       %y = [d1+(0:n-2)*(d2-d1)/(floor(n)-1) d2];
       
       quotient = (single(c2-c1))/(single(len)-single(1) + single(eps));%(d2-d1)/(floor(n)-1)
       for i=oneI32:len
           leftC(i) = (c1-HALF_OFFSET) + int32((single(i)-single(1))*quotient);
           rightC(i) = leftC(i)+ twoI32*HALF_OFFSET;
           if leftC(i) < oneI32
               leftC(i) = oneI32;
               if rightC(i) < oneI32
                  rightC(i) = oneI32;
               end
           end
           if rightC(i) > cW
               rightC(i) = cW;
           end
       end
           
       whiteCount = zeroI32;
       yellowCount = zeroI32;
       grayCount   = zeroI32;

       SumOfGotAlLeastOneWhitePixelInTheRow = zeroI32;
       SumOfGotAlLeastOneYellowPixelInTheRow = zeroI32;
           
       for i=oneI32:len
           gotAlLeastOneWhitePixelInTheRow = logical(false);
           gotAlLeastOneYellowPixelInTheRow = logical(false);
           for cv = leftC(i):rightC(i)
             
                  if tmpInImage_Y(Rs(i), cv) >= single(175/255)
                      whiteCount = whiteCount+oneI32;
                      gotAlLeastOneWhitePixelInTheRow = logical(true);
                  elseif tmpInImage_Cb(Rs(i), cv) >= single(90/255) && tmpInImage_Cb(Rs(i), cv) <= single(127/255) 
                      yellowCount = yellowCount+oneI32;
                      gotAlLeastOneYellowPixelInTheRow = logical(true);
                  else
                      grayCount = grayCount+oneI32;
                  end
           end
           if gotAlLeastOneWhitePixelInTheRow
             SumOfGotAlLeastOneWhitePixelInTheRow = SumOfGotAlLeastOneWhitePixelInTheRow+oneI32;
           end
           if gotAlLeastOneYellowPixelInTheRow
             SumOfGotAlLeastOneYellowPixelInTheRow = SumOfGotAlLeastOneYellowPixelInTheRow+oneI32;
           end
       end

       yellowVsTotal = single(yellowCount)/single(grayCount+yellowCount+whiteCount);
       whiteVsTotal = single(whiteCount)/single(grayCount+yellowCount+whiteCount);
        
       if yellowVsTotal > whiteVsTotal
           lineColorIdx(lineIdx) = YELLOW_COLOR;
           linearPixelRatio = single(SumOfGotAlLeastOneYellowPixelInTheRow)/single(len);             
       else
           lineColorIdx(lineIdx) = WHITE_COLOR;
           linearPixelRatio = single(SumOfGotAlLeastOneWhitePixelInTheRow)/single(len);
       end
       
       %% distinguish solid and broken lane markers
       % if we use yellowVsTotal(==whiteVsTotal) to find marker type (solid/broken)
       % it would not give accurate result; because in the patch we are searching 
       % for yellow/white pixel- we do not know what's the pecentage of gray pixels 
       % are there
       % that's why we are considering a different method; here we try to find one
       % yellow (==white) pixel in one row; once we find a yellow (==white) pixel
       % in the row we don't need to find anything in that row of the patch (ROI)

       if linearPixelRatio > single(0.8)
            solidBrokenIdx(lineIdx) = SOLID_MARKING;
       else
            solidBrokenIdx(lineIdx) = BROKEN_MARKING;
       end 
       
       if (lineColorIdx(lineIdx) == YELLOW_COLOR) && (solidBrokenIdx(lineIdx) == BROKEN_MARKING)
           colorAndTypeIdx(lineIdx) = YELLOW_BROKEN;
       elseif (lineColorIdx(lineIdx) == YELLOW_COLOR) && (solidBrokenIdx(lineIdx) == SOLID_MARKING)
           colorAndTypeIdx(lineIdx) = YELLOW_SOLID;
       elseif (lineColorIdx(lineIdx) == WHITE_COLOR) && (solidBrokenIdx(lineIdx) == BROKEN_MARKING)
           colorAndTypeIdx(lineIdx) = WHITE_BROKEN;
       elseif (lineColorIdx(lineIdx) == WHITE_COLOR) && (solidBrokenIdx(lineIdx) == SOLID_MARKING)
           colorAndTypeIdx(lineIdx) = WHITE_SOLID;
       end
       
   else
       lineColorIdx(lineIdx) = INVALID_COLOR;
       solidBrokenIdx(lineIdx) = INVALID_MARKING;
       colorAndTypeIdx(lineIdx) = INVALID_COLOR_OR_TYPE;
   end
end

3 仿真结果

4 参考文献

[1]王诗旋, 贺新升, 张荣辉,等. 基于Matlab和优化Hough变换的高速公路车道线检测方法[J].  2021(2011-8):29-29.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Matlab科研辅导帮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值