官方公开课 | Apollo自动驾驶入门课程

官方公开课

Apollo自动驾驶入门课程第①讲—无人驾驶概览

Apollo自动驾驶入门课程第②讲 — 高精地图

Apollo自动驾驶入门课程第③讲 — 定位

Apollo自动驾驶入门课程第④讲 — 感知(上)

Apollo自动驾驶入门课程第⑤讲 — 感知(下)

Apollo自动驾驶入门课程第⑥讲 — 预测

Apollo自动驾驶入门课程第⑦讲 — 规划(上)

Apollo自动驾驶入门课程第⑧讲 — 规划(下)

Apollo自动驾驶入门课程第⑨讲 — 控制(上)

零基础教程

零基础视频

Linux入门以及常用命令 | 百度传课

C语言入门 | 腾讯课堂

精通C++ | 腾讯课堂

官方视频教程 | Apollo视频课程

官方公开课 | Apollo自动驾驶入门课程

Docker基础

了解​ROS机器人操作系统

 

Apollo视频及学习图谱

百度Apollo平台与智能驾驶方案深度解析

百度Apollo开发者必看技能架构 | 图谱

 

Udacity无人驾驶课程列表

 无人驾驶第一课:从 Apollo 起步(课程免费)

 Udacity无人驾驶课程(Apollo)

Udacity无人驾驶入门课程

Udacity无人驾驶工程师课程

从零开始学习无人驾驶技术 — 车道检测–夏飞

这是第一篇。文章主要会以Udacity为主线,综合自己在学习过程中搜集的各种材料,取其精华,补其不足,力求通俗易懂,理论明确,实战有效,即作为一个学习总结,potentially又可以帮助对无人驾驶有兴趣但是零基础的朋友们 —— 注意这里的零基础是指未接触过无人驾驶领域,本系列还是需要一些简单的数学和机器学习知识。

因为本文是从零开始的第一篇,这里的车道检测是基础版本,需要满足几个先决条件:(1)无人车保持在同车道的高速路中行驶(2)车道线清晰可见(3)无人车与同车道内前车保持足够远的距离。

TLDR (or the take-away)

一个基础版的车道检测步骤主要分为以下几点:

  • Gray Scale Transformation
  • Gaussian Smoothing
  • Canny Edge Detection
  • ROI (Region of Interest) Based Edge Filtering
  • Hough Transformation
  • Lane Extrapolation

代码:Github链接

最后的效果如下视频所示,其中红线表示自动检测到的车道。

https://v.qq.com/x/page/u0377sik121.html

从图片开始谈起

无人车往往配备有数个camera,常见的情况是有一个camera固定在车的前方,用来perceive前方道路情况,生成视频。计算机对该视频进行分析,综合其他sensor的信息,对车辆行为进行指导。视频是由图片组成,如果能够成功检测图片上的车道,那我们就几乎解决了车道检测问题。下面是一张车辆行驶过程中的图片,让我们动手吧!

import matplotlib.image as mplimg
img = mplimg.imread('lane.jpg')

Gaussian Smoothing

Gaussian Smoothing是对图片apply一个Gaussian Filter,可以起到模糊图片和消除噪声的效果。其基本原理是重新计算图片中每个点的值,计算时取该点及其附近点的加权平均,权重符合高斯分布。下图左侧展示了一个kernel_size = 5的Gaussian Filter,55是高斯分布的中心点,341是网格中所有值的和。假设网格矩阵为Q,图片为I,新图片为I',则:

I'_{ij} = \frac{1}{341}\sum^{i+2}_{m = i-2}\ \sum^{j+2}_{n=j-2} Q_{mn} I_{mn}

Gaussian Filter是一种低通过滤器,能够抑制图片中的高频部分,而让低频部分顺利通过。那什么是图片的高频部分呢?下图给出了一个比较极端的例子。爱好摄影的朋友们都知道相机ISO适当时能够得到右侧图片,画质细腻;如果ISO过大,就会导致产生左侧图片,画质差,噪点多。这些噪点就是图片中的高频部分,表示了像素值剧烈升高或降低。

介绍完了Gaussian Filter,现在可以将其应用到我们的灰度图片上:

blur_ksize = 5  # Gaussian blur kernel size
blur_gray = cv2.GaussianBlur(gray, (blur_ksize, blur_ksize), 0, 0)

Canny Edge Detection

John F. Canny在1986年发明了Canny Edge Detection技术,其基本原理是对图片中各个点求gradient,gradient较大的地方往往是edge。Canny Edge Detection精妙的地方在于它有两个参数:low_threshold和high_threshold。算法先比较gradient与这两个threshold的关系,如果gradient > high_threshold,就承认这是一个edge point;如果gradient < low_threshold,就断定这不是edge point;对于其他的点,如果与edge point相连接,那么这个点被认为也是edge point,否则不是。

canny_lthreshold = 50  # Canny edge detection low threshold
canny_hthreshold = 150  # Canny edge detection high threshold
edges = cv2.Canny(blur_gray, low_threshold, high_threshold)

ROI Based Edge Filtering

Woohoo! It’s awesome! 经过了Canny Edge Detection,我们发现物体的轮廓都被检测到了!但是似乎东西有点儿太多了… 没关系,还有一个重要的条件没有用:camera相对于车是固定的,而无人车相对于车道的左右位置也是基本固定的,所以车道在camera视频中基本保持在一个固定区域内!据此我们可以画出一个大概的Region of Interest (ROI),过滤掉ROI之外的edges。

def roi_mask(img, vertices):
  mask = np.zeros_like(img)
  mask_color = 255
  cv2.fillPoly(mask, vertices, mask_color)
  masked_img = cv2.bitwise_and(img, mask)
  return masked_img

roi_vtx = np.array([[(0, img.shape[0]), (460, 325), 
                     (520, 325), (img.shape[1], img.shape[0])]])
roi_edges = roi_mask(edges, roi_vtx)

Hough Transformation

目前看起来我们似乎已经得到了车道线了呢,然而…并没有! 因为最终目标是得到exactly两条直线!而目前现在图中不仅有多条线,还有一些点状和块状区域,Hough Transformation的目的就是找到图中的线。

下图中左侧是image space,中间和右侧是Hough space。先看左侧和中间的图(右侧图见本节备注),image space中的一个点对应Hough space的一条线;image space中的两个点(x_1 \neq x_2)对应Hough space的两条相交线,且交点对应的线必经过image space的这两个点。

那么,如果Hough space中有多条线相交于一点,则在image space中对应的那些点应位于同一条线上,例如:

在实际操作中,我们往往将Hough space划分为网格状,如果经过一个格子的线的数目大于某threshold,我们认为这个经过这个格子的线在原image space对应的点应在同一条线上。具备了这些知识,我们可以用Hough Transformation来找线啦!

# Hough transform parameters
rho = 1
theta = np.pi / 180
threshold = 15
min_line_length = 40
max_line_gap = 20

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)

def hough_lines(img, rho, theta, threshold, 
                min_line_len, max_line_gap):
  lines = cv2.HoughLinesP(img, rho, theta, threshold, np.array([]),
                          minLineLength=min_line_len, 
                          maxLineGap=max_line_gap)
  line_img = np.zeros((img.shape[0], img.shape[1], 3), dtype=np.uint8)
  draw_lines(line_img, lines)
  return line_img


line_img = hough_lines(roi_edges, rho, theta, threshold, 
                       min_line_length, max_line_gap)

 

备注:如果image space中两个点x_1 = x_2,则其形成的直线斜率无限大,无法用中间的图表示,可以采用右侧的极坐标表示方式。

Lane Extrapolation

Almost there! 现在我们要根据得到的线计算出左车道和右车道,一种可以采用的步骤是:

  1. 根据斜率正负划分某条线属于左车道或右车道
  2. 分别对左右车道线移除outlier:迭代计算各条线的斜率与斜率均值的差,逐一移除差值过大的线
  3. 分别对左右车道线的顶点集合做linear regression,得到最终车道。

因为这部分代码有点儿多,就不贴在这里了,请参见我的Github代码。结果如下:

最最后,我们将结果和原图叠加:

cv2.addWeighted(img, 0.8, line_img, 1, 0)

图片任务完成!

回到视频上

现在我们将前面的代码打个包放到叫process_an_image的函数中,然后

from moviepy.editor import VideoFileClip
output = 'video_1_sol.mp4'
clip = VideoFileClip("video_1.mp4")
out_clip = clip.fl_image(process_an_image)
out_clip.write_videofile(output, audio=False)

将代码应用到三个不同的video上,看看结果!

视频1链接地址:

https://v.qq.com/x/page/u0377sik121.html

 

视频2链接地址:

https://v.qq.com/x/page/r037764yts3.html

 

视频3链接地址:

https://v.qq.com/x/page/o0377jc77sr.html

 

自动驾驶免费数据资源分享

今天发现一篇自动驾驶免费数据资源跟大家分享一下,希望大家留言补充

  1. 自动驾驶数据

很多自动驾驶公司都开放了一部分数据。很多其他文章也都有这方面的总结,documentation已经比较全面,这里就不赘述了。

Udacity数据
github.com/udacity/self
Udacity雷达数据
github.com/udacity/self
Mighty AI视觉分类数据
mty.ai/dataset/
Comma AI数据
research.comma.ai/
摄像头数据
robotcar-dataset.robots.ox.ac.uk
百度Apollo
github.com/ApolloAuto/a
人机交互数据
hcilab.org/research/hci
其他机器人数据
diyrobocars.com/open-da

2. 卫星高清

卫星高清图有很多用途。真正的卫星高清图比谷歌的卫星图要清楚很多倍。可以看清每一辆车、每一条斑马线。通过最新的卫星图,自动驾驶车可以提前预知道路情况,甚至可以分析转弯时候的视觉遮挡问题。

谷歌地球图片搜索
explorer.earthengine.google.com
美国地质调查局地图earthexplorer.usgs.gov/

3. 视频数据

SHRP2提供不错的视频资源。都是驾驶员安装在汽车前段的摄像头记录的各种撞车、剧烈颠簸、或是违章事件。视频都由人工处理过,详细解释了撞车原因。

SHRP2视频数据库insight.shrp2nds.us/dat

4. 路线规划

这里的路线规划不是自动驾驶的planner,而是普通意义上的A点到B点的路线。自从谷歌地图火遍大江南北,各种各样的API就应运而生。

HERE developer.here.com/plan
各种API wiki.openstreetmap.org/

5. 交通事故数据

通过分析交通事故,我们可以得出危险路段,也可以分析交通事故成因,自动驾驶车就不会重蹈覆辙。

SWIRTS tims.berkeley.edu/login
危险路段地图(旧金山)
sfgov.maps.arcgis.com/a

6. 环境数据

自动驾驶环境很复杂,天气、路况、行人等等,各个方面都需要考虑到。

天气API
openweathermap.org/api
darksky.net/dev
4G数据覆盖情况
opensignal.com/networks
路灯
product.itoworld.com/ma
施工路段
quickmap.dot.ca.gov/
Uber/Lyft流量
tncstoday.sfcta.org/
自行车流量
data.sfgov.org/Transpor
行人流量
data.sfgov.org/Transpor

7. 道路性质(旧金山)

道路性质直接决定自动驾驶车的技术难度。

车道数据 product.itoworld.com/ma
自行车车道 data.sfgov.org/Transpor
交通灯
data.sfgov.org/Transpor
路口
data.sfgov.org/Geograph
圆环
data.sfgov.org/Transpor
停车场
data.sfgov.org/Transpor
提车计时器
data.sfgov.org/Transpor
限速
data.sfgov.org/Transpor
公共交通站点
sfmta.com/reports/gtfs-