OpenCV的车道线检测

article/2025/10/2 22:03:40

资源下载地址:https://download.csdn.net/download/sheziqiong/85604275
资源下载地址:https://download.csdn.net/download/sheziqiong/85604275

final_mark.py是最终,前面的都是一部分一部分测试的功能,用的是霍夫变换拟合,测试视频附在压缩文件中。

关于OpenCV的车道线检测

前期芝士

1.1基本方法

1.1.1图像处理

图像处理主要是先对图像进行灰度处理,高斯模糊,然后对其进行canny边缘检测,最后对得到的图像进行roi掩膜处理,进一步缩小范围。

1.1.2霍夫变换

霍夫变换(Hough)是一个检测间断点边界形状的方法。它通过将图像坐标空间变换到参数空间,来实现直线与曲线的拟合。

在图像坐标空间中,经过点的直线表示为:

(1)

其中,参数a为斜率,b为截矩。其中,参数a为斜率,b为截矩。

通过点 点的直线有无数条,且对应于不同的a和b值。

如果将和视为常数,而将原本的参数a和b看作变量,则式子(1)可以表示为:

(2)

这样就变换到了参数平面ab。这个变换就是直角坐标中对于点的Hough变换。

该直线是图像坐标空间中的点在参数空间的唯一方程。考虑到图像坐标空间中的另一点,它在参数空间中也有相应的一条直线,表示为:

(3)

这条直线与点在参数空间的直线相交于一点,如图所示:

图 3直角变换中的直线霍夫变换

图像坐标空间中过点和点的直线上的每一点在参数空间ab上各自对应一条直线,这些直线都相交于点,而a0、b0就是图像坐标空间xy中点和点所确定的直线的参数。

反之,在参数空间相交于同一点的所有直线,在图像坐标空间都有共线的点与之对应。根据这个特性,给定图像坐标空间的一些边缘点,就可以通过Hough变换确定连接这些点的直线方程。

具体计算时,可以将参数空间视为离散的。建立一个二维累加数组,第一维的范围是图像坐标空间中直线斜率的可能范围,第二维的范围是图像坐标空间中直线截矩的可能范围。开始时初始化为0,然后对图像坐标空间的每一个前景点,将参数空间中每一个的离散值代入式子(2)中,从而计算出对应的值。每计算出一对都将对应的数组元素加1,即。所有的计算结束之后,在参数计算表决结果中找到的最大峰值,所对应的、就是源图像中共线点数目最多(共个共线点)的直线方程的参数;接下来可以继续寻找次峰值和第3峰值和第4峰值等等,它们对应于原图中共线点略少一些的直线。

对于上图的Hough变换空间情况如下图所示。

图 4直角坐标下的霍夫变换

1.1.3离群变换和最小二乘拟合

设置delta值,将不合理的斜率从斜率集中剔除。

利用numpy的最小二乘拟合将所有斜率大于0的点集和斜率小于0的点集分别拟合成两条直线。

1.1.4视频流的读写

对视频流逐帧读取并且逐帧处理,最后在进行逐帧播放即可。

1.2实验基本流程

  1. Canny边缘检测

  2. 手动分割路面区域

  3. 霍夫变换得到车道线

  4. 获取车道线并叠加到原始图像中

局部代码

2.1图像处理

2.1.1局部二值化处理

要对图像进行边缘检测,首先对图像进行灰度变换,使图像只包含一个通道的信息,然后比较各相邻像素间的亮度差别,亮度产生突变的地方就是边缘像素,将这些边缘像素点连接到一起就形成了边缘图像。www.biyezuopin.vip

那么首先要知道如何检测出边缘:

边缘有方向和幅值两个要素,通常对图像相邻域像素求取梯度来描述和检测边缘。

在进行边缘检测之前至少要将图像灰度化,因为梯度运算并不能反映色彩的变化差异,所以转换成只有一种颜色通道的灰度图像能够更好地进行边缘检测。

深入了解过图像二值化和边缘检测之后,我认为既可以直接使用灰度图像进行边缘检测,也可以二值化之后再进行边缘检测,二值化的目的是进一步简化灰度图像,使图像中的信息更加纯粹,边缘亮度变化更加明显。如果阈值选的较好还可以滤除不需要的弱边缘,使边缘处理后的图像轮廓更加清晰,效果如图。

图 5局部二值化图像得到的边缘检测图像

图 6灰度图的边缘检测图像

可以明显发现对二值化图像进行边缘检测比直接对灰度图进行边缘检测的效果要好,得到的边更宽,可以方便后续操作。

同时,显然局部二值化处理的结果要比全局二值化处理的结果好,效果如图:

明显全局二值化的图像已经不能看了。代码如下:def get_bin_img_1(*color_img*):"""局部自适应阈值二值化"""gray_img = cv2.cvtColor(*color_img*, cv2.COLOR_BGR2GRAY)binary = cv2.adaptiveThreshold(gray_img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 25, 10)return binarydef get_bin_img_2(*image*):"""全局自适应阈值二值化"""gray = cv2.cvtColor(*image*, cv2.COLOR_RGB2GRAY) \# 把输入图像灰度化ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY \| cv2.THRESH_TRIANGLE) # 直接阈值化是对输入的单通道矩阵逐像素进行阈值分割。return binary最后又测试了对边缘处理的图像二值化处理后再计算,效果也还可以,不过似乎差距不大,代码如下:def test_b_e(*color_img*):"""先边缘再二值化"""img = do_do_do(*color_img*)binary = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 25, 10)mask_img_gray = roi_mask(binary)lines = get_lines(mask_img_gray)draw_lines(*color_img*, lines)# return edge_imgreturn *color_img*return binary

最后权衡之下选择了对边缘处理的图像二值化处理后再计算的这种方法。

2.1.2高斯滤波参数选择

经过多次尝试,我选择gaussian_ksize=5, gaussian_sigmax=1,

代码如下:

gaussian = cv2.GaussianBlur(*color_img*, (*gaussian_ksize*, *gaussian_ksize*), *gaussian_sigmax*)

2.1.3对图像的roi掩膜处理

对图像进行了较为精确的测算,得出了视频对应的roi范围,效果如图:

def* roi_mask(*gray_img*):"""对gray_img进行掩膜:param gray_img: 灰度图,channels=1"""# poly_pts = np.array([[[125, 324], [235, 259], [325, 259], [435, 324]]])
# 视频1poly_pts = np.array([[[118, 243], [293, 112], [365, 110], [575, 243]]]) \#视频2mask = np.zeros_like(*gray_img*)mask = cv2.fillPoly(mask, *pts*=poly_pts, *color*=255)img_mask = cv2.bitwise_and(*gray_img*, mask)return img_mask

2.2车道线计算

2.2.1剔除离群点

利用斜率的合理性,剔除误差较大的点,代码如下

def* reject_abnormal_lines(*lines*, *threshold*=0.2):"""剔除不一致的线段"""slopes = [calculate_slope(line) for line in *lines*]while len(*lines*) \> 0:mean = np.mean(slopes)diff = [abs(s - mean) for s in slopes]idx = np.argmax(diff)if diff[idx] \> *threshold*:slopes.pop(idx)*lines*.pop(idx)else:breakreturn *lines

合理性判断

在绘制直线之前,对将要绘制的直线进行合理性判断,因为车道线不会突变,所以主要是利用上一帧的斜率以及大致斜率来排除,代码如下:

def* draw_lines(*img*, *lines*):"""绘制线段"""try:x = Falseglobal pre_linesleft_line, right_line = *lines*\# print(left_line)\# print((left_line[0][1] - left_line[1][1]) / (left_line[0][0] -
left_line[1][0]))if ((left_line[0][1] - left_line[1][1]) / (left_line[0][0] - left_line[1][0])) \> 0.5:"""print((left_line[0][1] - left_line[1][1])/ (left_line[0][0] - left_line[1][0]))"""cv2.line(img,tuple(left_line[0]),tuple(left_line[1]),color*=(0, 255, 255),thickness*=4,)x = Trueelse:left_line, right_line = pre_linesif ((left_line[0][1] - left_line[1][1])/ (left_line[0][0] - left_line[1][0])) > 0.5:cv2.line(*img*,tuple(left_line[0]),tuple(left_line[1]),*color*=(0, 255, 255),*thickness*=4,)x = False# print(right_line)if ((right_line[0][1] - right_line[1][1])/ (right_line[0][0] - right_line[1][0])) < -0.5:cv2.line(*img*,tuple(right_line[0]),tuple(right_line[1]),*color*=(0, 255, 255),*thickness*=4,)x = Trueelse:left_line, right_line = pre_linesif ((right_line[0][1] - right_line[1][1])(right_line[0][0] - right_line[1][0])) < -0.5:cv2.line(img,tuple(right_line[0]),tuple(right_line[1]),color=(0, 255, 255),thickness*=4,)x = Falseif x == True:pre_lines = linesexcept BaseException:return

资源下载地址:https://download.csdn.net/download/sheziqiong/85604275


http://chatgpt.dhexx.cn/article/kE3N2xPc.shtml

相关文章

动手学无人驾驶(7):车道线检测

最近在研究视觉语义地图&#xff0c;需要进行车道线检测&#xff0c;发现这篇车道线检测论文效果蛮好的 &#xff08;Ultra Fast Structure-aware Deep Lane Detection&#xff09;。论文作者在知乎上已经介绍过了&#xff1a;https://zhuanlan.zhihu.com/p/157530787&#xff…

高级车道线检测

基于图像处理相关技术的高级车道线检测&#xff08;可适用于弯道&#xff0c;车道线颜色不固定&#xff0c;路面阴影&#xff0c;亮光&#xff09; pipeline&#xff1a; 1.校准摄像头的畸变&#xff0c;使拍摄照片能够较完整的反映3D世界的情况 2.对每一帧图片做透视转换(pers…

传统方法车道线标注及相关知识

目录 一、图像二值化处理 1.Sobel算子绝对值 2.Sobel算子 3.倾斜角度 4.HLS颜色空间 5.二值图结合 二、车道线分割 1.仿射变换 2.车道线直方图 3.滑动窗口寻找车道线 4.车道线拟合 5.车道线区域标注 一、图像二值化处理 主要目的是通过二值化图像&#xff0c;使得车…

学习笔记之车道线相关记录

一. 车道线相关的知识 &&1.标线的分类 以下分类来自于百科&#xff1a; 按照道路交通标线的功能划分为&#xff1a;指示标线、警告标线和禁止标线。 按标划方法可分为&#xff1a;白色虚线、白色实线、黄色虚线、黄色实线、双白虚线、双白实线、双黄虚线和双黄实线…

关于python 最简单封装实例

一、 #定义一个类 class Person: #init是定义类实例初始化函数 ,没有返回return def __init__(self,name,area): self.name name self.area area #类里面定义方法 def run(self): print(self.name) …

Python软件封装打包

作者&#xff1a;Naples 链接&#xff1a;https://www.zhihu.com/question/32703639/answer/165326590 来源&#xff1a;知乎 著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。 Python Tkinter打包封装的方法有&#xff1a;PyInstaller, py…

Python封装、继承和多态

Python 语言在设计之初&#xff0c;就定位为一门面向对象的编程语言&#xff0c;“Python 中一切皆对象”。同时&#xff0c;Python 也支持面向对象的三大特征&#xff1a;封装、继承和多态。 一、封装 封装&#xff08;Encapsulation&#xff09;&#xff0c;即在设计类时&am…

python程序封装

python程序封装1 报错请执行pip install --upgrade setuptools 和 pip install --upgrade wheel 步骤如下&#xff1a; &#xff08;1&#xff09;安装pyinstaller&#xff0c;可以直接在cmd命令行中&#xff0c;输入命令“pip install pyinstaller”&#xff0c;安装pyinsta…

python封装程序

#终端/cmd命令下&#xff1a; 1.安装python Welcome to Python.org 2.安装pip pip PyPI 下载get-pip.py 在cmd窗口下执行&#xff0c;python */*/get-pip.py&#xff08;*为文件所在位置&#xff09; *如果安装好后出现 不是内部命令的情况 需要在环境中添加&#xff…

制作python包,封装成可用模块

制作python包&#xff0c;封装成可用模块 首先编写py程序: printtest.py #coding: utf-8 def test():print(print test)if __name__ __main__:test() 将以上.py文件做成python模块&#xff0c;需要在相同目录下创建setup.py文件&#xff0c;setup.py中输入配置信息: #cod…

Python 程序封装-打包成exe程序

Python 程序封装-打包成exe程序 前言一、 Python 打包工具—Pyinstaller二、打包具体过程1. 打包成仅包含一个独立的exe程序2. 打包成包含文件夹的程序&#xff0c;内有相关的依赖库&#xff08;推荐&#xff09;3. 其他的打包命令 三、注意事项 欢迎学习交流&#xff01; 邮箱…

怎么python程序封装?此文详解

python程序封装1 步骤如下: (1)安装pyinstaller,可以直接在cmd命令行中,输入命令“pip install pyinstaller”,安装pyinstaller (2)进入py代码的保存目录,这里py代码放在“E:\python学习\python_work” (3)cmd,输入命令:e:,进入e盘 (4)继续输入:E:\pytho…

Python封装

在用新电脑做python的封装的时候&#xff0c;出现了一系列的问题。在这里简单写一下Python的封装的一些流程以及可能出现的问题和解决方法吧。 封装我选择的是pyinstaller 首先是安装pyinstaller&#xff1a;Python 默认并不包含 PyInstaller 模块&#xff0c;因此需要自行安…

python之类的封装

博主简介&#xff1a;原互联网大厂tencent员工&#xff0c;网安巨头Venustech员工&#xff0c;阿里云开发社区专家博主&#xff0c;微信公众号java基础笔记优质创作者&#xff0c;csdn优质创作博主&#xff0c;创业者&#xff0c;知识共享者,欢迎关注&#xff0c;点赞&#xff…

Python入门——函数封装

当工程量比较大时&#xff0c;我们可以采取“函数封装”的方法实现函数的重复使用&#xff0c;避免“重复造轮子”。 步骤 手动创建一个包&#xff0c;只需进行以下 2 步操作&#xff1a; 新建一个文件夹&#xff0c;文件夹的名称就是新建包的包名&#xff1b;在该文件夹中&…

Python学习基础笔记五十八——封装

封装&#xff1a;广义上的面向对象封装。代码的保护。面向对象的思想本身就是一种封装&#xff0c;只让自己的对象能调用自己类中的方法。 狭义的封装概念&#xff1a;面向对象的三大特性之一&#xff1a;让属性和方法都藏起来&#xff0c;不让你看见。 例1&#xff1a; clas…

Python必备封装基本代码~Python函数

大家好&#xff0c;我是辣条 最近不少粉丝通过文末找到辣条让我分享一些代码封装这一块的内容&#xff0c;今天他来了~ 一遍看不懂就收起来慢慢看&#xff0c;我写的还是很详细的&#xff0c;一定是能轻松拿捏住Python函数的&#xff0c;不过还请记得多多支持辣条&#xff0c;…

PMP学习笔记顺口溜

区分几种组织结构 老板项目为系统&#xff1b; 只有职能为职能&#xff1b; 多个部门多部门&#xff0c; 多个项目为项目 职能项目为矩阵&#xff0c;项强为强&#xff0c;项弱为弱&#xff1b; 项目职能一般大 &#xff1a;平衡 网络分散为虚拟

PMP学习笔记 零 启动

PMP 学习笔记 零 启动 我为什么要学习PMP 我是一个程序猿&#xff0c;别人让我做什么&#xff0c;我就去做什么&#xff0c;提出什么需求我就完成&#xff0c;但是渐渐的我不满足成为一个工具人&#xff0c;就开始也开始设计功能&#xff0c;和抛开产品经理独自完成一些需求&…

我的PMP学习考试心得

01看书学习是基础&#xff0c;但更需要深化理解 备考期间&#xff0c;我通读了PMBOK&#xff0c;认真观看了视频教程和小红书&#xff0c;按照班主任的要求循序渐进&#xff0c;慢慢掌握了基本的知识点。因为缺少基础&#xff0c;所以只能通过反复记忆&#xff0c;特别是利用每…