文章目录
0 前言
无人驾驶技术是机器学习为主的一门前沿领域,在无人驾驶领域中机器学习的各种算法随处可见,今天学长给大家介绍无人驾驶技术中的车道线检测。
1 车道线检测
在无人驾驶领域每一个任务都是相当复杂,看上去无从下手。那么面对这样极其复杂问题,我们解决问题方式从先尝试简化问题,然后由简入难一步一步尝试来一个一个地解决问题。车道线检测在无人驾驶中应该算是比较简单的任务,依赖计算机视觉一些相关技术,通过读取 camera 传入的图像数据进行分析,识别出车道线位置,我想这个对于 lidar 可能是无能为力。所以今天我们就从最简单任务说起,看看有哪些技术可以帮助我们检出车道线。
我们先把问题简化,所谓简化问题就是用一些条件限制来缩小车道线检测的问题。我们先看数据,也就是输入算法是车辆行驶的图像,输出车道线位置。
更多时候我们如何处理一件比较困难任务,可能有时候我们拿到任务时还没有任何思路,不要着急也不用想太多,我们先开始一步一步地做,从最简单的开始做起,随着做就会有思路,同样一些问题也会暴露出来。我们先找一段视频,这段视频是我从网上一个关于车道线检测项目中拿到的,也参考他的思路来做这件事。好现在就开始做这件事,那么最简单的事就是先读取视频,然后将其显示在屏幕以便于调试。
2 目标
检测图像中车道线位置,将车道线信息提供路径规划。
3 检测思路
- 图像灰度处理
- 图像高斯平滑处理
- canny 边缘检测
- 区域 Mask
- 霍夫变换
- 绘制车道线
4 代码实现
4.1 视频图像加载
import cv2
import numpy as np
import sys
import pygame
from pygame.locals import *
class Display(object):
def __init__(self,Width,Height):
pygame.init()
pygame.display.set_caption('Drive Video')
self.screen = pygame.display.set_mode((Width,Height),0,32)
def paint(self,draw):
self.screen.fill([0,0,0])
draw = cv2.transpose(draw)
draw = pygame.surfarray.make_surface(draw)
self.screen.blit(draw,(0,0))
pygame.display.update()
if __name__ == "__main__":
solid_white_right_video_path = "test_videos/丹成学长车道线检测.mp4"
cap = cv2.VideoCapture(solid_white_right_video_path)
Width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
Height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
display = Display(Width,Height)
while True:
ret, draw = cap.read()
draw = cv2.cvtColor(draw,cv2.COLOR_BGR2RGB)
if ret == False:
break
display.paint(draw)
for event in pygame.event.get():
if event.type == QUIT:
sys.exit()
上面代码学长就不多说了,默认大家对 python 是有所了解,关于如何使用 opencv 读取图片网上代码示例也很多,大家一看就懂。这里因为我用的是 mac 有时候显示视频图像可能会有些问题,所以我们用 pygame 来显示 opencv 读取图像。这个大家根据自己实际情况而定吧。值得说一句的是 opencv 读取图像是 BGR 格式,要想在 pygame 中正确显示图像就需要将 BGR 转换为 RGB 格式。
4.2 车道线区域
现在这个区域是我们根据观测图像绘制出来,
def color_select(img,red_threshold=200,green_threshold=200,blue_threshold=200):
ysize,xsize = img.shape[:2]
color_select = np.copy(img)
rgb_threshold = [red_threshold, green_threshold, blue_threshold]
thresholds = (img[:,:,0] < rgb_threshold[0]) \
| (img[:,:,1] < rgb_threshold[1]) \
| (img[:,:,2] < rgb_threshold[2])
color_select[thresholds] = [0,0,0]
return color_select
效果如下:
4.3 区域
我们要检测车道线位置相对比较固定,通常出现车的前方,所以我们通过绘制,也就是仅检测我们关心区域。通过创建 mask 来过滤掉那些不关心的区域保留关心区域。
4.4 canny 边缘检测
有关边缘检测也是计算机视觉。首先利用梯度变化来检测图像中的边,如何识别图像的梯度变化呢,答案是卷积核。卷积核是就是不连续的像素上找到梯度变化较大位置。我们知道 sobal 核可以很好检测边缘,那么 canny 就是 sobal 核检测上进行优化。
# 示例代码,
def canny_edge_detect(img):
gray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
kernel_size = 5
blur_gray = cv2