Advertisement

使用OpenCV进行实时车道检测

阅读量:

作者|ABHISHEK SHARMA 编译|VK 来源|Analytics Vidhya

大约十年前,在谷歌试验了一辆原型车的时候, 我预见了我的第一辆自动驾驶汽车的存在与实现。我对这一想法产生了浓厚的兴趣与探索欲望. 不可否认地, 我不得不静待时机直至这些技术理念得以公开分享. 现在回想起来, 等待的过程虽然漫长却确实在某种程度上证明了其必要性!

我最近试验了几种与计算机视觉相关的无人驾驶汽车概念,并涵盖车道检测技术。试想一下,这个技术实际上是设计任何一款无人驾驶汽车的关键模块。

在本次视频内容里, 我们将要搭建并开发一个基于当前的技术架构的车道检测系统, 重点介绍相关算法原理和实现细节。

听起来很棒哦!在本教程中,我们计划利用OpenCV库来进行道路检测以及自动驾驶相关的技术实现。此外,在本教程中我们还将引入Python编程语言来辅助开发过程。

目录

  1. 理解车道检测的概念

  2. 理解问题陈述

  3. 什么是帧掩码?

  4. 车道检测的图像预处理

  5. 用OpenCV在Python中实现车道检测

理解车道检测的概念

那么什么是车道检测?以下是百度百科对车道的定义:

车道线也可称为行车线或车行道线,在供车辆行驶的道路设施中普遍使用。
通常设于各类道路设施中,在普通公路与高速公路均可见其身影。
其中 highway遵循更为严格的规范管理,
如单行道、双向车道等。

对其进行明确界定至关重要。在构建系统的过程中必须保证每一个细节都清晰明确。

正如所述,在我的先前论述中指出的那样

以下是一些随机道路图像(第一行)及其检测到的车道(第二行):

理解问题陈述

我们的目标是实时识别视频中的车道区域。实现车道检测可通过多种技术手段进行。采用基于深度学习的学习方法时,在标注数据集上进行模型训练是一个有效途径。此外,在某些情况下可利用已有的预训练模型。

不过,在介绍完上述复杂方法后,在本文中我会向您展示一种更为简便的方式实现车道检测的任务。具体而言,在本研究中我们关注的目标是在无需依赖复杂的人工智能模型的前提下完成这一目标。
在此过程中,则会采用Python中的OpenCV库作为工具来进行具体实现。

下面是我们将要处理的视频的一个帧:

正如我们在图中所见,在这张图片上我们可以观察到有四个被白色的分道线分开的道路区域

除了车道标识线外,在该场景中还包含多种其他物体。道路两侧布置了车辆、路沿式护栏以及路灯等设施,在视频序列中每帧画面都呈现出不同的场景配置。这种配置有效地模拟了真实的道路驾驶环境

为此必须,在处理车道检测问题之前过滤掉驾驶环境中无关的对象

我们能够做的第一步就是精简关注点。与其采用整个帧的技术手段来处理图像信息而不愿只使用帧的一部分。在下面的图像中,除了车道标记外的所有图像元素均被隐去。当车辆在路面上行驶时,在该区域内的车道标线可能会部分或全部地被遮挡。

在下一节中, 我计划向大家演示如何编辑视频帧以定位特定区域. 同时也会介绍一些必要的图像预处理操作.

什么是帧掩码(Frame Mask)?

在这一段中,在这里帧掩码只是一个NumPy数组。当我们要在图像上应用掩码时,则只需将目标区域的像素值设为0、255或其他任意数值即可。以下是一个具体的图像遮蔽实例:在此图中某一特定区域的所有像素已经被赋值为0:

这是一种非常简单但有效的从图像中去除不需要的区域和对象的方法。

车道检测的图像预处理

随后我们将对输入视频中的每一帧施加遮罩效果。接着采用图像二值化处理并结合霍夫直线变换方法来识别车道标线的位置。

图像阈值化

在该方法中用于处理灰度图像的方法是将每个像素的数值根据设定的阈值区分成两种代表黑白的颜色数值。基于此,在这种情况下(即当单个像素的数值超过该阈值时),该像素会被赋予一种特定的数值;反之,则会被赋予另一种数值。

如上所述,在对蒙版图像施加阈值处理后,在输出图像中仅能获得对应的车道标线信息。当前情况下,在输出图像中借助霍夫线变换能够较为便捷地识别出这些标记符号。

霍夫线变换

霍夫线变换是一种检测任何可以用数学方法表示的形状的方法。

例如;被它可以用来检测包括矩形、圆、三角形和直线在内的各种形状;我们感兴趣的是被用来检测能够表示为直线形式的车道标线。

此为OpenCV Python Tutorials网站上的相关文档:https://openCV-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_houghlines/py_houghlines.html

在执行图像阈值化后对图像应用霍夫线变换将提供以下输出:

我们需要对所有帧执行此过程,然后将生成的帧缝合到新视频中。

用OpenCV在Python中实现车道检测

真的时候开始用Python编程语言开发这个车道检测应用!我认为选择Google Colab作为开发环境更为合适,因为它提供了强大的计算资源。

首先导入所需的库:

复制代码
    import os
    import re
    import cv2
    import numpy as np
    from tqdm import tqdm_notebook
    import matplotlib.pyplot as plt
读取视频帧

我已经成功从YouTube平台的某个视频中撷取了若干个视频片段。请参考以下链接获取:AI模型演示集的压缩包文件。

复制代码
    # 获取帧的文件名
    col_frames = os.listdir('frames/')
    col_frames.sort(key=lambda f: int(re.sub('\D', '', f)))
    
    # 加载帧
    col_images=[]
    for i in tqdm_notebook(col_frames):
    img = cv2.imread('frames/'+i)
    col_images.append(img)

让我们绘制一个帧:

复制代码
    # 指定一个索引
    idx = 457
    
    # plot frame
    plt.figure(figsize=(10,10))
    plt.imshow(col_images[idx][:,:,0], cmap= "gray")
    plt.show()
帧掩码创建

我们关注的一个部分是一个多边形形状。为了便于后续处理过程,在遮蔽其他区域之前, 我们必须先确定多边形的具体坐标参数, 然后利用这些参数生成相应的帧掩码过程.

复制代码
    # 创建0矩阵
    stencil = np.zeros_like(col_images[idx][:,:,0])
    
    # 指定多边形的坐标
    polygon = np.array([[50,270], [220,160], [360,160], [480,270]])
    
    # 用1填充多边形
    cv2.fillConvexPoly(stencil, polygon, 1)
复制代码
    # 画出多边形
    plt.figure(figsize=(10,10))
    plt.imshow(stencil, cmap= "gray")
    plt.show()
复制代码
    # 应用该多边形作为掩码
    img = cv2.bitwise_and(col_images[idx][:,:,0], col_images[idx][:,:,0], mask=stencil)
    
    # plot masked frame
    plt.figure(figsize=(10,10))
    plt.imshow(img, cmap= "gray")
    plt.show()
图像预处理

为了实现对视频帧进行一系列图像预处理步骤以便检测所需车道信息。这些操作主要包括:

为了实现对视频帧进行一系列图像预处理步骤以便检测所需车道信息。这些操作主要包括:

  1. 图像阈值化

  2. 霍夫线变换

1.图像阈值化
复制代码
    # 应用图像阈值化
    ret, thresh = cv2.threshold(img, 130, 145, cv2.THRESH_BINARY)
    
    # 画出图像
    plt.figure(figsize=(10,10))
    plt.imshow(thresh, cmap= "gray")
    plt.show()
2.霍夫线变换
复制代码
    lines = cv2.HoughLinesP(thresh, 1, np.pi/180, 30, maxLineGap=200)
    
    # 创建原始帧的副本
    dmy = col_images[idx][:,:,0].copy()
    
    # 霍夫线
    for line in lines:
      x1, y1, x2, y2 = line[0]
      cv2.line(dmy, (x1, y1), (x2, y2), (255, 0, 0), 3)
    
    # 画出帧
    plt.figure(figsize=(10,10))
    plt.imshow(dmy, cmap= "gray")
    plt.show()

当前我们将对每一个帧执行所有这些操作,并且将结果帧存储于新的存储目录中:

复制代码
    cnt = 0
    
    for img in tqdm_notebook(col_images):
    
      # 应用帧掩码
      masked = cv2.bitwise_and(img[:,:,0], img[:,:,0], mask=stencil)
    
      # 应用图像阈值化
      ret, thresh = cv2.threshold(masked, 130, 145, cv2.THRESH_BINARY)
    
      # 应用霍夫线变换
      lines = cv2.HoughLinesP(thresh, 1, np.pi/180, 30, maxLineGap=200)
      dmy = img.copy()
    
      #画出检测到的线
      try:
    for line in lines:
      x1, y1, x2, y2 = line[0]
      cv2.line(dmy, (x1, y1), (x2, y2), (255, 0, 0), 3)
    
    cv2.imwrite('detected/'+str(cnt)+'.png',dmy)
    
      except TypeError: 
    cv2.imwrite('detected/'+str(cnt)+'.png',img)
    
      cnt+= 1
视频准备
复制代码
    # 输入帧的路径
    pathIn= 'detected/'
    
    #输出视频路径
    pathOut = 'roads_v2.mp4'
    
    # 视频每秒的帧数
    fps = 30.0
复制代码
    from os.path import isfile, join
    
    # 获取帧的文件名
    files = [f for f in os.listdir(pathIn) if isfile(join(pathIn, f))]
    files.sort(key=lambda f: int(re.sub('\D', '', f)))

接下来,我们将把检测到的车道上的所有帧放入一个列表中:

复制代码
    frame_list = []
    
    for i in tqdm_notebook(range(len(files))):
    filename=pathIn + files[i]
    #读取每一个文件
    img = cv2.imread(filename)
    height, width, layers = img.shape
    size = (width,height)
    
    #将帧插入图像数组
    frame_list.append(img)

最后,我们现在可以使用下面的代码将帧合并为视频:

复制代码
    # 写入视频
    out = cv2.VideoWriter(pathOut,cv2.VideoWriter_fourcc(*'DIVX'), fps, size)
    
    for i in range(len(frame_array)):
    out.write(frame_array[i])
    
    out.release()

这就完成了Python中的车道检测系统。

结尾

本教程中讲述了关于基本车道检测技术的知识。未采用传统的深度学习模型或复杂的图像分析算法来实现这一目标。相比之下,在实现这一目标的过程中,并非依赖于复杂的深度学习架构或繁复的特征提取机制;相反地,则完全是依靠一系列基础的图像预处理操作完成。

但是,在许多情况下(方案/技术/系统)会不可行。例如,在缺少车道标识或车流量过大的情况下会发生故障(失灵/失效)。为了应对这些挑战(问题),在车道检测中采用了更为复杂的解决方案(方法)。

该平台提供了一份全面指南:使用OpenCV进行实时车道检测。本文的目标是为读者提供一个逐步的指导方针,帮助他们理解车道检测的核心概念及其在实时环境下的实现。这份指南使用一种广为人知的开源计算机视觉工具——OpenCV——来识别并跟踪移动物体在视频流中的位置。识别并跟踪移动物体是现代计算机视觉中不可或缺的一项任务。本文将带领您从头到尾掌握这一技术——从头到尾——无需深厚的数学背景知识或编程技能。

欢迎关注磐创AI博客站: http://panchuang.net/

sklearn机器学习中文官方文档: http://sklearn123.com/

欢迎关注磐创博客资源汇总站: http://docs.panchuang.net/

全部评论 (0)

还没有任何评论哟~