0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

自动驾驶之——初级车道线检测

ml8z_IV_Technol 来源:lq 2019-02-04 16:10 次阅读

在介绍计算机视觉技术前,我想先讨论一下这次分享的输入和输出。

输入

一张摄像机拍摄到的道路图片,图片中需要包含车道线。如下图所示。

输出

图像坐标系下的左右车道线的直线方程和有效距离。将左右车道线的方程绘制到原始图像上,应如下图所示。

在输入和输出都定义清楚后,我们就开始使用计算机视觉技术,一步步完成对原始图像的处理。

原始图像

认识图像前,我们需要先回顾一下在初中所学的物理知识——光的三原色,光的三原色分别是红色(Red)、绿色(Green)和蓝色(Blue)。通过不同比例的三原色组合形成不同的可见光色。如下图所示。

图片出处:https://zhidao.baidu.com/question/197911511.html

图像中的每个像素点都是由RGB(红绿蓝)三个颜色通道组成。为了方便描述RGB颜色模型,在计算机中约束了每个通道由暗到亮的范围是0~255。

当某个像素点的R通道数值为255,G和B通道数值为0时,实际表现出的颜色就是最亮的红色;当某个像素点的RGB三通道都为255时,所表示的是最亮的白色;当某个像素点的RGB三通道都为0时,就会显示最暗的黑色。在RGB颜色模型中,不会有比[255,255,255]的组合更亮的颜色了。

根据以上理论基础,一幅彩色图像,其实就是由三幅单通道的图像叠加,如下图所示。

图片出处:Udacity无人驾驶工程师

以基于python的OpenCV为例,读取名为test_img.jpg的图片到计算机内存中的代码如下:

import cv2

img = cv2.imread('image_name.jpg')

读取图像后,我们可以将图像看做一个二维数组,每个数组元素中存了三个值,分别是RGB三个通道所对应的数值。

OpenCV定义了,图像的原点(0,0)在图片的左上角,横轴为X,朝右,纵轴为Y,朝下,如下图所示。

需要注意的是,由于OpenCV的早期开发者习惯于使用BGR顺序的颜色模型,因此使用OpenCV的imread()读到的像素,每个像素的排列是按BGR,而不是常见的RGB,代码编写时需要注意。

灰度处理

考虑到处理三个通道的数据比较复杂,我们先将图像进行灰度化处理,灰度化的过程就是将每个像素点的RGB值统一成同一个值。灰度化后的图像将由三通道变为单通道,单通道的数据处理起来就会简单许多。

通常这个值是根据RGB三通道的数值进行加权计算得到。人眼对RGB颜色的敏感度不同,对绿色最敏感,权值较高,对蓝色最不敏感,权值较低。

坐标为(x,y)的像素点进行灰度化操作的具体计算公式如下:

调用OpenCV中提供的cvtColor()函数,能够方便地对图像进行灰度处理

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 由于使用cv2.imread()读到的img的数据排列为BGR,因此这里的参数为BGR2GRAY

灰度处理后的图像如下图所示:

边缘提取

为了突出车道线,我们对灰度化后的图像做边缘处理。“边缘”就是图像中明暗交替较为明显的区域。车道线通常为白色或黄色,地面通常为灰色或黑色,因此车道线的边缘处会有很明显的明暗交替。

常用的边缘提取算法Canny算法和Sobel算法,它们只是计算方式不同,但实现的功能类似。可以根据实际要处理的图像,选择算法。哪种算法达到的效果更好,就选哪种。

以Canny算法为例,选取特定的阈值后,对灰度图像进行处理,即可得到的边缘提取的效果图。

low_threshold = 40

high_threshold = 150

canny_image = cv2.Canny(gray, low_threshold, high_threshold)

感兴趣区域选择

边缘提取完成后,需要检测的车道线被凸显出来了。为了实现自车所在车道的车道线检测,我们需要将感兴趣的区域(Region of Interest)提取出来。提取感兴趣区域最简单的方式就是“截取”。

首先选定一个感兴趣区域,比如下图所示的蓝色三角形区域。对每个像素点的坐标值进行遍历,如果发现当前点的坐标不在三角区域内,则将该点涂“黑”,即将该点的像素值置为0。

为了实现截取功能,可以封装一下OpenCV的部分函数,定义一个region_of_interest函数:

def region_of_interest(img, vertices):

#定义一个和输入图像同样大小的全黑图像mask,这个mask也称掩膜

#掩膜的介绍,可参考:https://www.cnblogs.com/skyfsm/p/6894685.html

mask = np.zeros_like(img)

#根据输入图像的通道数,忽略的像素点是多通道的白色,还是单通道的白色

if len(img.shape) > 2:

channel_count = img.shape[2] # i.e. 3 or 4 depending on your image

ignore_mask_color = (255,) * channel_count

else:

ignore_mask_color = 255

#[vertices]中的点组成了多边形,将在多边形内的mask像素点保留,

cv2.fillPoly(mask, [vertices], ignore_mask_color)

#与mask做"与"操作,即仅留下多边形部分的图像

masked_image = cv2.bitwise_and(img, mask)

return masked_image

源码出自:https://github.com/udacity/CarND-LaneLines-P1/blob/master/P1.ipynb

封装完函数后,我们将感兴趣的区域输入,实现边缘提取后的图像的截取。

#图像像素行数 rows = canny_image .shape[0] 540行

#图像像素列数 cols = canny_image .shape[1] 960列

left_bottom = [0, canny_image .shape[0]]

right_bottom = [canny_image .shape[1], canny_image .shape[0]]

apex = [canny_image .shape[1]/2, 310]

vertices = np.array([ left_bottom, right_bottom, apex ], np.int32)

roi_image = region_of_interest(canny_image, vertices)

截取后的图像入下图所示:

霍夫变换

经过灰度处理、边缘检测、感兴趣区域截取后,我们终于将左右车道线从复杂的图像中提取出来了。接下来,我们使用霍夫变换来提取图像中的直线(段)。

霍夫变换是一种特征检测方法,其原理和推导过程可以参看经典霍夫变换(Hough Transform)https://blog.csdn.net/yuyuntan/article/details/80141392。

在图像中使用霍夫变换不仅能够识别图像中的直线,还能识别出图像中的圆、椭圆等特征。OpenCV为我们提供了霍夫变换检测直线的函数,可以通过设置不同的参数,检测不同长度的线段。由于车道线存在虚线的可能,因此线段的检测长度不能设置地太长,否则短线段会被忽略掉。

OpenCV的霍夫变换直线检测函数使用方法如下:

rho = 2 # distance resolution in pixels of the Hough grid

theta = np.pi/180 # angular resolution in radians of the Hough grid

threshold = 15 # minimum number of votes (intersections in Hough grid cell)

min_line_length = 40 #minimum number of pixels making up a line

max_line_gap = 20 # maximum gap in pixels between connectable line segments

# Hough Transform 检测线段,线段两个端点的坐标存在lines中

lines = cv2.HoughLinesP(roi_image, rho, theta, threshold, np.array([]),

min_line_length, max_line_gap)

封装一个绘图函数,实现把线段绘制在图像上的功能,以实现线段的可视化

def draw_lines(img, lines, color=[255, 0, 0], thickness=2):

for line in lines:

for x1,y1,x2,y2 in line:

cv2.line(img, (x1, y1), (x2, y2), color, thickness) # 将线段绘制在img上

将得到线段绘制在原始图像上

import numpy as np

line_image = np.copy(img) # 复制一份原图,将线段绘制在这幅图上

draw_lines(line_image, lines, [255, 0, 0], 6)

结果如下图:

可以看出,虽然右车道线的线段不连续,但已经很接近我们想要的输出结果了。

数据后处理

霍夫变换得到的一系列线段结果跟我们的输出结果还是有些差异。为了解决这些差异,需要对我们检测到的数据做一定的后处理操作。

实现以下两步后处理,才能真正得到我们的输出结果。

1.计算左右车道线的直线方程

根据每个线段在图像坐标系下的斜率,判断线段为左车道线还是右车道线,并存于不同的变量中。随后对所有左车道线上的点、所有右车道线上的点做一次最小二乘直线拟合,得到的即为最终的左、右车道线的直线方程。

2.计算左右车道线的上下边界

考虑到现实世界中左右车道线一般都是平行的,所以可以认为左右车道线上最上和最下的点对应的y值,就是左右车道线的边界。

基于以上两步数据后处理的思路,我们重新定义draw_lines()函数,将数据后处理过程写入该函数中。

def draw_lines(img, lines, color=[255, 0, 0], thickness=2):

left_lines_x = []

left_lines_y = []

right_lines_x = []

right_lines_y = []

line_y_max = 0

line_y_min = 999

for line in lines:

for x1,y1,x2,y2 in line:

if y1 > line_y_max:

line_y_max = y1

if y2 > line_y_max:

line_y_max = y2

if y1 < line_y_min:

line_y_min = y1

if y2 < line_y_min:

line_y_min = y2

k = (y2 - y1)/(x2 - x1)

if k < -0.3:

left_lines_x.append(x1)

left_lines_y.append(y1)

left_lines_x.append(x2)

left_lines_y.append(y2)

elif k > 0.3:

right_lines_x.append(x1)

right_lines_y.append(y1)

right_lines_x.append(x2)

right_lines_y.append(y2)

#最小二乘直线拟合

left_line_k, left_line_b = np.polyfit(left_lines_x, left_lines_y, 1)

right_line_k, right_line_b = np.polyfit(right_lines_x, right_lines_y, 1)

#根据直线方程和最大、最小的y值反算对应的x

cv2.line(img,

(int((line_y_max - left_line_b)/left_line_k), line_y_max),

(int((line_y_min - left_line_b)/left_line_k), line_y_min),

color, thickness)

cv2.line(img,

(int((line_y_max - right_line_b)/right_line_k), line_y_max),

(int((line_y_min - right_line_b)/right_line_k), line_y_min),

color, thickness)

根据对线段的后处理,即可得到符合输出要求的两条直线方程的斜率、截距和有效长度。将后处理后的结果绘制在原图上,如下图所示:

处理视频

视频其实就是一帧帧连续不断的图像,使用读取视频的库,将视频截取成一帧帧图像,然后使用上面的灰度处理、边缘提取、感兴趣区域选择、霍夫变换和数据后处理,得到车道线检测结果,再将图片结果拼接成视频,就完成了视频中的车道线检测。

视频可以看出,当汽车在下坡时,车头会发生俯仰,造成感兴趣区域的变化,因此检测到的有效长度有所变化。可见本算法需要针对车辆颠簸的场景进行优化。

以上就是《初识图像之初级车道线检测》的全部内容,关于这个项目的全部内容,可以在优达学城(Udacity)无人驾驶工程师学位首页试听,建议读者亲身学习一遍。

在实际编写车道线检测代码的过程中,你会发现,每一步都需要调很多参数,才能满足后续算法的处理要求。可见,本算法无法应用在不同光照条件的场景中,鲁棒性较差;同时,由于霍夫变换检测直线本身的缺陷,面对弯道场景时,无法很好地将弯道检测出来。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 计算机视觉
    +关注

    关注

    8

    文章

    1698

    浏览量

    45965
  • 无人驾驶
    +关注

    关注

    98

    文章

    4053

    浏览量

    120424
  • 自动驾驶
    +关注

    关注

    784

    文章

    13779

    浏览量

    166350

原文标题:自动驾驶之——初级车道线检测

文章出处:【微信号:IV_Technology,微信公众号:智车科技】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    FPGA在自动驾驶领域有哪些应用?

    低,适合用于实现高效的图像算法,如车道线检测、交通标志识别等。 雷达和LiDAR处理:自动驾驶汽车通常会使用雷达和LiDAR(激光雷达)等多种传感器来获取环境信息。FPGA能够协助完成
    发表于 07-29 17:09

    【mBot申请】自动驾驶

    申请理由:很喜欢硬件功能完善的机器人,这款机器人上面的多种传感器及器件均用过,超声波传感器和巡线传感器还未接触过,想了解下这种传感器的灵敏度和精度,而且近年来自动驾驶汽车兴起,还希望借此做一款
    发表于 11-30 15:30

    【话题】特斯拉首起自动驾驶致命车祸,自动驾驶的冬天来了?

    `特斯拉首起自动驾驶致命车祸,自动驾驶的冬天来了?“一个致命的事故一定是由多个小的错误组成的。”  7月初,特斯拉发表博客叙述了NHTSA(美国国家公路交通安全管理局)正在着手调查第一起Tesla
    发表于 07-05 11:14

    自动驾驶真的会来吗?

      实际上,按照美国高速公路安全委员会(NHTSA)的5个分级,特斯拉所使用的自动驾驶属于第2级别的“混合功能自动化”,该级别主要包含能同时提供组合式的自动化功能。比如自动巡航和
    发表于 07-21 09:00

    细说关于自动驾驶那些事儿

    展示了停车场自动驾驶,其中运用了超音波和影像感测技术侦测障碍物、车道线和车位等周边环境,并结合GPS、电子图资、惯性测量组件(Inertial Measurement Unit,IMU)和轮速计,控制
    发表于 05-15 17:49

    自动驾驶的到来

    的车载处理器仍然将是半导体厂商在汽车电子领域的重点投资及发展方向。中国自动驾驶面临的挑战  首先中国不同地域以及城镇之间在道路基础设施方面存在差异,包括路标、车道线、红绿灯等设置各有不同。中国特色
    发表于 06-08 15:25

    速腾聚创首次发布LiDAR算法 六大模块助力自动驾驶

    车道标识线检测、障碍物检测、动态物体跟踪、障碍物分类识别等六大功能模块,有助于自动驾驶车辆立刻获得LiDAR感知能力。今年4月份,速腾聚创
    发表于 10-13 16:08

    自动驾驶汽车的定位技术

    标识、地图匹配、GPS、或导航信标进行定位。位置的计算方法包括三角测量法、三边测量法和模型匹配算法等。从这个角度而言,IMU也是自动驾驶必备的部件。惯性传感器(IMU)是检测加速度与旋转运动的高频
    发表于 05-09 04:41

    如何让自动驾驶更加安全?

    最近,国内多个城市开始发放自动驾驶的开放道路测试牌照,意味着自动驾驶的汽车可以在公共道路上进行测试。不过,驾驶安全性仍是社会关注的焦点,美国优步公司进行自动驾驶技术测试发生致命撞击事故
    发表于 05-13 00:26

    自动驾驶汽车的处理能力怎么样?

    作在未来20 - 30年中,自动驾驶汽车(AV)将改变我们的驾驶习惯、运输行业并更广泛地影响社会。 我们不仅能够将汽车召唤到我们的家门口并在使用后将其送走,自动驾驶汽车还将挑战个人拥有汽车的想法,并
    发表于 08-07 07:13

    如何实现车道线分割

    深度学习方法实现车道线分割之二(自动驾驶车道线分割)
    发表于 05-22 10:16

    联网安全接受度成自动驾驶的关键

    仍不能避免零件老旧的问题,使得自动驾驶汽车相关零组件保固赔偿措施,将会影响自动驾驶未来商用化的推动时程进度。  
    发表于 08-26 06:45

    自动驾驶线控底盘VCU功能介绍

    满足自动驾驶远程遥控的线控底盘整车控制器VCU1 自动驾驶线控底盘VCU功能介绍满足自动驾驶及遥控驾驶
    发表于 09-07 06:30

    【KV260视觉入门套件试用体验】八、VITis AI自动驾驶多任务执行MultiTask V3

    是一种模型,旨在同时执行自动驾驶场景中的不同任务,同时实现优异的性能和效率。这些任务包括对象检测、分割、车道检测、可行驶区域分割和深度估算,这些都是
    发表于 09-26 16:43

    【实战】Python+OpenCV车道线检测识别项目:实现L2级别自动驾驶必备(配套课程+平台实践)

    的一个必备技能——车道线检测。本文将详细介绍一个车道线检测项目的过程,从图像采集到
    的头像 发表于 12-16 15:42 224次阅读
    【实战】Python+OpenCV<b class='flag-5'>车道</b><b class='flag-5'>线</b><b class='flag-5'>检测</b>识别项目:实现L2级别<b class='flag-5'>自动驾驶</b>必备(配套课程+平台实践)