百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

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

toyiye 2024-07-06 00:35 13 浏览 0 评论

近年来,基于人工智能的车道检测算法得到了广泛的研究。与传统的基于特征的方法相比,许多方法表现出了优越的性能。然而,当使用具有挑战性的图像时,其准确率通常仍在低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 cv2
import numpy as np
def 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时,这个函数就不适用了

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

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码