news 2026/5/11 4:27:14

基于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/5/9 6:37:26

NXP88W8801-WIFI芯片解读

​​​​​ 一、产品概述 88W8801 是一款高度集成的单频段&#xff08;2.4GHz&#xff09;IEEE 802.11n 1x1 系统级芯片&#xff08;SoC&#xff09;&#xff0c;专为支持 WiFi 产品的高吞吐量&#xff08;HT&#xff09;数据速率而设计。 该设备集成了直接序列扩频&#xff08…

作者头像 李华
网站建设 2026/5/8 11:22:19

还在手动搭Maven多模块?这款IDEA插件让我效率提升10倍(真实体验)

引言最近带团队做新项目&#xff0c;发现刚毕业的学弟还在用最原始的方式搭建Maven多模块项目——手动建文件夹、写pom依赖、调整目录结构...整整折腾了一下午&#xff0c;连基础框架都没搭好。不光是新人&#xff0c;我们这些工作好几年的老鸟每次开新项目也得重复这些机械操作…

作者头像 李华
网站建设 2026/5/10 18:52:20

适用于LiblibLiblibTV跨项目的商业化体系重构实践

背景 1. 业务动机&#xff1a;为什么需要跨项目复用 本 monorepo 中有两个面向用户的产品&#xff1a; 主站项目&#xff1a;社区型 Web 应用&#xff0c;提供模型浏览、AI 生图/生视频、训练等核心功能&#xff0c;是最早的产品形态TV 项目&#xff1a;面向大屏/新场景的独立应…

作者头像 李华