opencv python智能车道检测,助力无人驾驶

近年来,基于人工智能的车道检测算法得到了广泛的研究。与传统的基于特征的方法相比,许多方法表现出了优越的性能。然而,当使用具有挑战性的图像时,其准确率通常仍在低80%或高90%之间,甚至更低。

准确可靠的车道检测是车道保持(LK)、变道自动化(LCA)和车道偏离警告(LDW)功能的关键特性。车道检测的研究可以追溯到20世纪80年代。世纪之交后,LDW和LK已经商业化,有些车辆甚至有LCA。DARPA和早期ADAS产品发起的自动驾驶挑战进一步推动了车道检测系统的发展。然而,由于不利的光照/天气条件和其他物体的存在,车道检测仍然是一个具有挑战性的问题。

车道检测可通过使用单目摄像机、立体摄像机、激光雷达等实现[4]。相机因其丰富的内容功能和低廉的价格而最受欢迎。

深度学习(DL)提出了一种新的数据驱动方法,并且比大多数基于特征的方法获得了更好的性能。虽然DL系统在许多应用中取得了优异的性能,但它们经常被用作'黑匣子',其性能没有保证。这限制了它们在安全关键任务中的应用,例如自动驾驶的车道检测。

我们也可以从静态的路标和路标中推断出路标和路标。基于特征的方法,如ELAS,通常在执行车道检测/跟踪任务之前预先检测所有可能的场景线索。对于基于卷积神经网络(CNN)的方法,这种场景信息在网络结构中是隐藏/隐含的。如果能先了解场景布局,将整个图像分割成几何区域,再聚焦于车道标识区域,则分类精度有望提高。

另一个重要的决定是CNN应该生成什么样的车道标签。许多现有的基于CNN的方法生成像素级的车道标记标志、车道区域掩码或参数化车道线。

对于大多数基于CNN的车道检测方法,输出是图像视图中像素级的车道实例掩码。然而,自主驾驶的期望输出是控制相关参数,即车辆横向偏移、航向角和曲率。为了填补这一空白,需要一些后处理程序,例如,反透视图(IPM)和车道模型拟合。由于车辆是运动的,道路并不总是平坦的,光是摄像机的内参数和外参数不足以计算摄像机与世界坐标之间的变换矩阵。需要更好的车道模型或附加程序,如消失点估计。

OpenCV+python实现的车道检测

深度学习加速了车道检测的精度,本文先介绍一下基于OpenCV的车道检测原理,当然精度虽然没有深度学习的高,但具体思想还是有类似的地方

import cv2import numpy as npdef canny(frame): gray = cv2.cvtColor(frame,cv2.COLOR_RGB2GRAY) blur = cv2.GaussianBlur(gray,(5,5),0) canny = cv2.Canny(blur,50,150) return canny

首先,我们建立几个子函数,canny子函数用来接收一个需要检测的照片,并使用高斯滤波函数对图像进行处理

高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。

cv2.GussianBlur()函数

语法:GaussianBlur(src,ksize,sigmaX [,dst [,sigmaY [,borderType]]])-> ds

t——src输入图像;图像可以具有任意数量的通道,这些通道可以独立处理,但深度应为CV_8U,CV_16U,CV_16S,CV_32F或CV_64F。

——dst输出图像的大小和类型与src相同。

——ksize高斯内核大小。 ksize.width和ksize.height可以不同,但​它们都必须为正数和奇数,也可以为零,然后根据sigma计算得出。

——sigmaX X方向上的高斯核标准偏差。

——sigmaY Y方向上的高斯核标准差;

如果sigmaY为零,则将其设置为等于sigmaX;

如果两个sigmas为零,则分别从ksize.width和ksize.height计算得出;

为了完全控制结果,而不管将来可能对所有这些语义进行的修改,建议指定所有ksize,sigmaX和sigmaY。

然后使用cv2.Canny函数进行边缘检测

edge = cv2.Canny(image, threshold1, threshold2[, edges[, apertureSize[, L2gradient ]]])

参数解释

· image:源图像

· threshold1:阈值1

· threshold2:阈值2

· apertureSize:可选参数,Sobel算子的大小

其中,较大的阈值2用于检测图像中明显的边缘,但一般情况下检测的效果不会那么完美,边缘检测出来是断断续续的。所以这时候用较小的第一个阈值用于将这些间断的边缘连接起来。

函数返回的是二值图,包含检测出的边缘,最后子函数返回边缘检测的2值化图片

代码截图

def region_of_in(frame):  height = frame.shape[0]  polygons = np.array([[(0,height),(500,0),(800,0),(1300,550),(1100,height)]])  mask = np.zeros_like(frame)  cv2.fillPoly(mask,polygons,255)  masked = cv2.bitwise_and(frame,mask)  return masked

此子涵主要用于处理边缘检测后的图片,以便获取mask,只保留车道线

代码截图

def display_line(frame,lines): line_image = np.zeros_like(frame) if lines is not None: for line in lines: x1,y1,x2,y2 = line.reshape(4) cv2.line(line_image,(x1,y1),(x2,y2),(0,255,0),1) return line_image

此子函数主要用于检测车道线,并显示

代码截图

img = cv2.imread('7.jpg')image = np.copy(img)canny = canny(image)cropped = region_of_in(canny)lines = cv2.HoughLinesP(cropped,1,np.pi/180,100,minLineLength = 5, maxLineGap=300)line_image = display_line(image,lines)frame = cv2.addWeighted(image,0.8,line_image,1,1)cv2.imshow('canny',frame)cv2.waitKey(0)

我们利用3个子函数对一张照片进行车道检测,首先我们读取一张照片,使用canny子函数进行图片边缘车道检测,然后使用region_of_in子函数进行mask的检测

cv2.HoughLinesP()函数可以查找直线段,我们把边缘检测的图片给到cv2.HoughLinesP()检测图片中的直线,然后使用display子函数显示检测到的直线

cv2.HoughLinesP()函数原型:HoughLinesP(image, rho, theta, threshold, lines=None, minLineLength=None, maxLineGap=None) · image: 必须是二值图像,推荐使用canny边缘检测的结果图像; · rho: 线段以像素为单位的距离精度,double类型的,推荐用1.0 · theta: 线段以弧度为单位的角度精度,推荐用numpy.pi/180 · threshod: 累加平面的阈值参数,int类型,超过设定阈值才被检测出线段,值越大,基本上意味着检出的线段越长,检出的线段个数越少。根据情况推荐先用100试试· lines:这个参数的意义未知,发现不同的lines对结果没影响,但是不要忽略了它的存在 · minLineLength:线段以像素为单位的最小长度,根据应用场景设置 · maxLineGap:同一方向上两条线段判定为一条线段的最大允许间隔(断裂),超过了设定值,则把两条线段当成一条线段,值越大,允许线段上的断裂越大,越有可能检出潜在的直线段

代码截图

最后,我们使用图像混合加权实现图片的融合,主要函数为cv2.addWeighted函数

cv2.addWeighted(src1, alpha, src2, beta, gamma[, dst[, dtype]]) → dst

参数说明· src1 – first input array.· alpha – weight of the first array elements.· src2 – second input array of the same size and channel number as src1.· beta – weight of the second array elements.· dst – output array that has the same size and number of channels as the input arrays.· gamma – scalar added to each sum.· dtype – optional depth of the output array; when both input arrays have the same depth,   dtype can be set to -1, which will be equivalent to src1.depth().

此函数可以用一下矩阵表达式来代替:

dst = src1 * alpha + src2 * beta + gamma;

由参数说明可以看出,被叠加的两幅图像必须是尺寸相同、类型相同的;并且,当输出图像array的深度为CV_32S时,这个函数就不适用了

以上检测方法,只能检测直线的车道线,当检测圆弧过渡的车道线,就不是那么适合了,使用此方法只能简单的对车道检测,有时其检测结果也会出现不尽人意的时候

车道检测

(0)

相关推荐

  • 二值化处理与边缘检测

    问题:我在提取图像边缘的时候,首先对图像进行灰度变换,之后进行二值处理,最后进行边缘检测得到边缘图像. 但是在查阅资料的过程中我经常发现很多人忽略二值化的步骤,直接进行边缘检测:还有很多人在实现某些功 ...

  • 使用 OpenCV 和 Tesseract 对图像中的感兴趣区域 (ROI) 进行 OCR

    重磅干货,第一时间送达 在这篇文章中,我们将使用 OpenCV 在图像的选定区域上应用 OCR.在本篇文章结束时,我们将能够对输入图像应用自动方向校正.选择感兴趣的区域并将OCR 应用到所选区域. 这 ...

  • (三)OpenCV图像处理

    直接 直接用霍夫直线检测,效果差; 通过图像形态学操作来寻找直线,霍夫获取位置信息与显示. #include <opencv2/opencv.hpp>#include <iostre ...

  • 实战:使用 OpenCV 的自动驾驶汽车车道检测(附代码)

    重磅干货,第一时间送达 一.边缘检测 我们将使用 Canny 进行边缘检测.如果你不确定这是什么,请查阅相关资料,对于后文的阅读会有帮助. def canyEdgeDetector(image): e ...

  • 【OpenCV读取标记点坐标】管道测速

    文章目录 一.项目简介 二.思考步骤 1. 图像二值化 2. 滤波去噪 3. Canny算法检测边缘 4. 查找轮廓并计算 5. 绘制轮廓并表示质心 三.测试结果 四.工程代码 一.项目简介 昨天一个 ...

  • OpenCV探索之路(十一):轮廓查找和多边形包围轮廓

    Canny一类的边缘检测算法可以根据像素之间的差异,检测出轮廓边界的像素,但它没有将轮廓作为一个整体.所以要将轮廓提起出来,就必须将这些边缘像素组装成轮廓. OpenCV中有一个很强大的函数,它可以从 ...

  • 《HALCON机器视觉与算法原理编程实践》第10章 边缘检测

    文章目录 10.1 像素级边缘提取 10.1.1 经典的边缘检测算子 10.1.2 边缘检测的一般流程 10.1.3 sobel_amp算子 10.1.4 edges_image算子 10.1.5 其 ...

  • 使用霍夫变换检测车道线

    重磅干货,第一时间送达 车道线检测是自动驾驶汽车的重要组成部分之一,有很多方法可以做到这一点.本文,我们将使用最简单的霍夫变换方法. 本文分为三个部分: 第一部分:高斯模糊+ Canny边缘检测 第二 ...

  • 一文解读经典霍夫变换(Hough Transform)

    视觉/图像重磅干货,第一时间送达 新机器视觉 最前沿的机器视觉与计算机视觉技术 206篇原创内容 公众号 来源: Hello AI World 引言 本文讲述霍夫变换的一些内容,并加入一些理解性东西, ...

  • 基于OpenCV的车辆变道检测

    重磅干货,第一时间送达 本期教程我们将和小伙伴们一起研究如何使用计算机视觉和图像处理技术来检测汽车在行驶中时汽车是否在改变车道!大家一定听说过使用OpenCV 的haar级联文件可以检测到面部.眼睛等 ...

  • 基于OpenCV的表格文本内容提取

    重磅干货,第一时间送达 小伙伴们可能会觉得从图像中提取文本是一件很麻烦的事情,尤其是需要提取大量文本时.PyTesseract是一种光学字符识别(OCR),该库提了供文本图像. PyTesseract ...