news 2026/4/15 17:24:05

基于Opencv和Python的车道线检测系统(带UI界面)实现之旅

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于Opencv和Python的车道线检测系统(带UI界面)实现之旅

基于Opencv和Python的车道线检测系统(带UI界面) 在自动驾驶中,让汽车保持在车道线内是非常重要的,所以这次我们来说说车道线的检测。 我们主要用到的是openCV, numpy, matplotlib几个库。 主要包括下面这么几个步骤: 1. 图像加载; 2. 图像预处理:图片灰度化,高斯滤波; 3. Cany边缘检测; 4. 需要区域检测; 5. 霍夫直线检测 ; 6. .直线拟合; 7. 车道线叠加; 8. 图片和视频测试; 9. 可视化界面pyqt5

在自动驾驶这个充满魅力与挑战的领域,汽车能够精准地保持在车道线内行驶,那可是重中之重。今天,咱就来唠唠如何搭建一个基于Opencv和Python的车道线检测系统,而且还带酷炫的UI界面哦。

基于Opencv和Python的车道线检测系统(带UI界面) 在自动驾驶中,让汽车保持在车道线内是非常重要的,所以这次我们来说说车道线的检测。 我们主要用到的是openCV, numpy, matplotlib几个库。 主要包括下面这么几个步骤: 1. 图像加载; 2. 图像预处理:图片灰度化,高斯滤波; 3. Cany边缘检测; 4. 需要区域检测; 5. 霍夫直线检测 ; 6. .直线拟合; 7. 车道线叠加; 8. 图片和视频测试; 9. 可视化界面pyqt5

咱们主要会用到openCVnumpymatplotlib这几个厉害的库。整个实现过程呢,大致可以拆解为以下几个关键步骤。

1. 图像加载

首先得把图像给加载进来呀,这就好比我们得先把要处理的原材料准备好。在Python里用OpenCV加载图像非常方便,就像下面这样:

import cv2 image = cv2.imread('test_image.jpg')

这里通过cv2.imread函数,把名为test_image.jpg的图像读进来了,并且存储在image变量里。如果图像路径不对或者图像格式不支持,那可能就加载失败咯,所以路径和格式都得留意下。

2. 图像预处理:图片灰度化,高斯滤波

加载进来的图像一般是彩色的,有时候为了后续处理方便,咱们得把它灰度化。而且图像里可能会有些噪声,这时候就需要高斯滤波来平滑一下。

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) blurred = cv2.GaussianBlur(gray, (5, 5), 0)

cv2.cvtColor函数把彩色图像imageBGR格式转成了灰度图gray。而cv2.GaussianBlur则对灰度图进行了高斯滤波,(5, 5)是高斯核的大小,数字越大,图像就越模糊,也就平滑得更厉害,0表示根据高斯核大小自动计算标准差。

3. Canny边缘检测

经过预处理后,就可以用Canny算法来找图像中的边缘啦。

edges = cv2.Canny(blurred, 50, 150)

这里cv2.Canny函数接收三个参数,第一个是经过高斯滤波后的图像blurred,第二个50是低阈值,第三个150是高阈值。低于低阈值的边缘会被丢弃,高于高阈值的边缘会被保留,介于两者之间的,只有当它们和高阈值边缘相连时才会被保留。

4. 需要区域检测

图像里可能有很多边缘,但我们只关心车道线所在的区域,所以得把这个区域给检测出来。这时候可以通过定义一个多边形区域来实现。

import numpy as np height, width = edges.shape roi_vertices = np.array([[(0, height), (width / 2, height / 2), (width, height)]], dtype=np.int32) def region_of_interest(image, vertices): mask = np.zeros_like(image) match_mask_color = 255 cv2.fillPoly(mask, vertices, match_mask_color) masked_image = cv2.bitwise_and(image, mask) return masked_image cropped_edges = region_of_interest(edges, roi_vertices)

这里先定义了图像的高度和宽度,然后创建了一个多边形顶点数组roivertices,这个多边形就是我们认为车道线可能出现的区域。regionofinterest函数创建了一个和图像大小一样的全零掩码mask,然后用cv2.fillPoly函数把定义的多边形区域填充为白色(matchmaskcolor = 255),最后通过cv2.bitwiseand操作,只保留了图像中在多边形区域内的部分。

5. 霍夫直线检测

检测出感兴趣区域的边缘后,就可以用霍夫变换来找直线啦,因为车道线基本可以看作是直线嘛。

lines = cv2.HoughLinesP(cropped_edges, rho=2, theta=np.pi / 180, threshold=50, lines=np.array([]), minLineLength=40, maxLineGap=10)

cv2.HoughLinesP函数里,cropped_edges是输入图像,rho是距离精度,theta是角度精度,threshold是阈值,只有检测到的直线上的点超过这个阈值才会被保留,minLineLength是最小直线长度,小于这个长度的直线会被忽略,maxLineGap是同一直线两点之间的最大间隔。

6. 直线拟合

找到的直线可能比较杂乱,我们需要对这些直线进行拟合,得到更平滑的车道线。这里以拟合左右两条车道线为例。

left_lines = [] right_lines = [] for line in lines: x1, y1, x2, y2 = line[0] slope = (y2 - y1) / (x2 - x1) if (x2 - x1)!= 0 else 0 if slope < 0: left_lines.append(line) else: right_lines.append(line) def average_slope_intercept(lines): if len(lines) == 0: return None left_x = [] left_y = [] for line in lines: x1, y1, x2, y2 = line[0] left_x.extend([x1, x2]) left_y.extend([y1, y2]) fit = np.polyfit(left_x, left_y, 1) fit_fn = np.poly1d(fit) return fit_fn left_fit = average_slope_intercept(left_lines) right_fit = average_slope_intercept(right_lines)

先把找到的直线根据斜率分成左右两组,然后通过averageslopeintercept函数对每组直线进行拟合,这里用np.polyfit函数来拟合一次多项式(也就是直线),np.poly1d函数生成拟合后的直线函数。

7. 车道线叠加

有了拟合后的车道线,就可以把它们画回到原图像上啦。

def draw_lines(image, lines): if lines is not None: for line in lines: x1, y1, x2, y2 = line[0] cv2.line(image, (x1, y1), (x2, y2), (0, 255, 0), thickness=5) return image image_with_lines = draw_lines(image.copy(), lines)

draw_lines函数遍历直线列表,用cv2.line函数在图像上画出绿色((0, 255, 0))、线宽为5的直线,最后返回画好直线的图像。

8. 图片和视频测试

上面都是针对单张图片的处理,要是想处理视频,其实思路差不多,就是一帧一帧地处理视频图像。

cap = cv2.VideoCapture('test_video.mp4') while cap.isOpened(): ret, frame = cap.read() if not ret: break gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) blurred = cv2.GaussianBlur(gray, (5, 5), 0) edges = cv2.Canny(blurred, 50, 150) cropped_edges = region_of_interest(edges, roi_vertices) lines = cv2.HoughLinesP(cropped_edges, rho=2, theta=np.pi / 180, threshold=50, lines=np.array([]), minLineLength=40, maxLineGap=10) image_with_lines = draw_lines(frame.copy(), lines) cv2.imshow('Video', image_with_lines) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()

这里用cv2.VideoCapture打开视频文件,然后在循环里一帧一帧读取视频,对每帧图像进行前面提到的那些处理步骤,最后用cv2.imshow显示处理后的视频帧,按q键可以退出循环并释放资源。

9. 可视化界面pyqt5

最后,咱们来给这个车道线检测系统加上一个UI界面,用pyqt5库来实现。

import sys from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QPushButton, QFileDialog from PyQt5.QtGui import QPixmap import cv2 class App(QWidget): def __init__(self): super().__init__() self.title = '车道线检测系统' self.left = 100 self.top = 100 self.width = 800 self.height = 600 self.initUI() def initUI(self): self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) self.label = QLabel(self) self.label.setGeometry(100, 100, 600, 400) btn = QPushButton('选择图片', self) btn.setGeometry(300, 500, 200, 50) btn.clicked.connect(self.openFileNameDialog) self.show() def openFileNameDialog(self): options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog fileName, _ = QFileDialog.getOpenFileName(self, "选择图片", "", "All Files (*);;JPEG Files (*.jpg);;PNG Files (*.png)", options=options) if fileName: image = cv2.imread(fileName) # 这里添加图像车道线检测处理代码,和前面单张图片处理类似 processed_image = self.process_image(image) cv2.imwrite('processed.jpg', processed_image) pixmap = QPixmap('processed.jpg') self.label.setPixmap(pixmap) def process_image(self, image): # 这里实现图像的车道线检测处理步骤,和前面单张图片处理类似 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) blurred = cv2.GaussianBlur(gray, (5, 5), 0) edges = cv2.Canny(blurred, 50, 150) cropped_edges = region_of_interest(edges, roi_vertices) lines = cv2.HoughLinesP(cropped_edges, rho=2, theta=np.pi / 180, threshold=50, lines=np.array([]), minLineLength=40, maxLineGap=10) image_with_lines = draw_lines(image.copy(), lines) return image_with_lines if __name__ == '__main__': app = QApplication(sys.argv) ex = App() sys.exit(app.exec_())

这里创建了一个App类继承自QWidget,在initUI方法里设置了窗口标题、大小,添加了一个标签用来显示图片,一个按钮用来选择图片。openFileNameDialog方法里实现了选择图片后进行车道线检测处理并显示处理后图片的功能,process_image方法就是具体的车道线检测处理步骤,和前面单张图片处理类似。

通过这一系列步骤,咱们就实现了一个基于Opencv和Python的带UI界面的车道线检测系统啦,是不是还挺有意思的!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/15 14:59:22

《P4602 [CTSC2018] 混合果汁》

题目描述小 R 热衷于做黑暗料理&#xff0c;尤其是混合果汁。商店里有 n 种果汁&#xff0c;编号为 0,1,⋯,n−1 。i 号果汁的美味度是 di​&#xff0c;每升价格为 pi​。小 R 在制作混合果汁时&#xff0c;还有一些特殊的规定&#xff0c;即在一瓶混合果汁中&#xff0c;i 号…

作者头像 李华
网站建设 2026/4/15 14:58:15

从实验室到实战场:WEEX BUILDERS 巴黎站,AI 交易的开发者叙事正在成形

巴黎的夜&#xff0c;比想象中更热闹。在塞纳河畔不远的一处活动空间里&#xff0c;终端界面在台上同时亮起&#xff0c;策略回测曲线与系统日志在投影幕上不断刷新。这里不是一场常规分享会&#xff0c;而是 WEEX BUILDERS 全球巡回巴黎站 的现场——开发者、量化研究者与技术…

作者头像 李华
网站建设 2026/4/15 14:59:22

【C++】异常处理机制全解析

文章目录一、C 异常的底层实现机制1. 核心思想&#xff1a;异常表 栈展开 (Stack Unwinding)2. 零成本异常处理&#xff08;GCC/Clang&#xff09;3. MSVC 的 SEH 实现二、核心关键字的原理1. throw&#xff1a;异常触发的核心2. try&#xff1a;异常监控域标记3. catch&#…

作者头像 李华
网站建设 2026/4/14 21:16:18

Jimeng LoRA保姆级教程:文件夹自动扫描+safetensors识别+自然排序配置

Jimeng LoRA保姆级教程&#xff1a;文件夹自动扫描safetensors识别自然排序配置 1. 项目简介 今天给大家介绍一个特别实用的工具——Jimeng LoRA测试系统。如果你正在训练LoRA模型&#xff0c;或者需要测试不同训练阶段的模型效果&#xff0c;这个工具能帮你节省大量时间。 …

作者头像 李华
网站建设 2026/4/7 21:26:10

零基础玩转SDPose-Wholebody:一键部署全身姿态检测模型

零基础玩转SDPose-Wholebody&#xff1a;一键部署全身姿态检测模型 1. 项目概述 SDPose-Wholebody是一个基于扩散先验技术的全身姿态估计模型&#xff0c;能够精准检测人体133个关键点。这个模型特别适合想要快速上手人体姿态检测的初学者&#xff0c;因为它提供了完整的Dock…

作者头像 李华
网站建设 2026/3/21 7:33:42

通义千问轻量模型:开发者API文档检索效率提升35%

通义千问轻量模型&#xff1a;开发者API文档检索效率提升35% 1. 引言&#xff1a;开发者每天浪费在找文档上的时间 如果你是一名开发者&#xff0c;下面这个场景你一定不陌生&#xff1a;为了调用一个API&#xff0c;你需要先找到它的官方文档。你打开搜索引擎&#xff0c;输…

作者头像 李华