Python基于YOLOv8和OpenCV实现车道线和车辆检测

使用YOLOv8(You Only Look Once)和OpenCV实现车道线和车辆检测,目标是创建一个可以检测道路上的车道并识别车辆的系统,并估计它们与摄像头的距离。该项目结合了计算机视觉技术和深度学习物体检测。

1、系统主要功能

  • 车道检测:使用边缘检测和霍夫线变换检测道路车道。
  • 汽车检测:使用 YOLOv8 模型识别汽车并在汽车周围绘制边界框。
  • 距离估计:使用边界框大小计算检测到的汽车与摄像头的距离。

2、环境要求

  • OpenCV:用于图像处理和车道检测。
  • Ultralytics YOLOv8:用于车辆检测。
  • NumPy:用于数组操作。
pip install opencv-python-headless numpy ultralytics

opencv-pythonopencv-python-headless 区别是 OpenCV 的 Python 包,主要区别在于是否包含 GUI 相关的功能。

opencv-python
  • 包含 GUI 功能:支持窗口显示、鼠标事件等图形界面操作。
  • 依赖:需要 GUI 库(如 GTK、Qt)支持。
  • 适用场景:适用于需要显示图像或与用户交互的环境,如桌面应用。
opencv-python-headless
  • 不包含 GUI 功能:去除了窗口显示和用户交互功能。
  • 依赖:无需 GUI 库,适合无图形界面的环境。
  • 适用场景:适用于服务器或无图形界面的环境,如远程服务器、Docker 容器。
选择建议
  • 如果需要显示图像或与用户交互,选择 opencv-python
  • 如果仅需图像处理且无图形界面需求,选择 opencv-python-headless

3、代码

import cv2
import numpy as np
import math
import time
from ultralytics import YOLO  # YOLOv8 module# Function to mask out the region of interest
def region_of_interest(img, vertices):mask = np.zeros_like(img)match_mask_color = 255cv2.fillPoly(mask, vertices, match_mask_color)masked_image = cv2.bitwise_and(img, mask)return masked_image# Function to draw the filled polygon between the lane lines
def draw_lane_lines(img, left_line, right_line, color=[0, 255, 0], thickness=10):line_img = np.zeros_like(img)poly_pts = np.array([[(left_line[0], left_line[1]),(left_line[2], left_line[3]),(right_line[2], right_line[3]),(right_line[0], right_line[1])]], dtype=np.int32)# Fill the polygon between the linescv2.fillPoly(line_img, poly_pts, color)# Overlay the polygon onto the original imageimg = cv2.addWeighted(img, 0.8, line_img, 0.5, 0.0)return img# The lane detection pipeline
def pipeline(image):height = image.shape[0]width = image.shape[1]region_of_interest_vertices = [(0, height),(width / 2, height / 2),(width, height),]# Convert to grayscale and apply Canny edge detectiongray_image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)cannyed_image = cv2.Canny(gray_image, 100, 200)# Mask out the region of interestcropped_image = region_of_interest(cannyed_image,np.array([region_of_interest_vertices], np.int32))# Perform Hough Line Transformation to detect lineslines = cv2.HoughLinesP(cropped_image,rho=6,theta=np.pi / 60,threshold=160,lines=np.array([]),minLineLength=40,maxLineGap=25)# Separating left and right lines based on slopeleft_line_x = []left_line_y = []right_line_x = []right_line_y = []if lines is None:return imagefor line in lines:for x1, y1, x2, y2 in line:slope = (y2 - y1) / (x2 - x1) if (x2 - x1) != 0 else 0if math.fabs(slope) < 0.5:  # Ignore nearly horizontal linescontinueif slope <= 0:  # Left laneleft_line_x.extend([x1, x2])left_line_y.extend([y1, y2])else:  # Right laneright_line_x.extend([x1, x2])right_line_y.extend([y1, y2])# Fit a linear polynomial to the left and right linesmin_y = int(image.shape[0] * (3 / 5))  # Slightly below the middle of the imagemax_y = image.shape[0]  # Bottom of the imageif left_line_x and left_line_y:poly_left = np.poly1d(np.polyfit(left_line_y, left_line_x, deg=1))left_x_start = int(poly_left(max_y))left_x_end = int(poly_left(min_y))else:left_x_start, left_x_end = 0, 0  # Defaults if no lines detectedif right_line_x and right_line_y:poly_right = np.poly1d(np.polyfit(right_line_y, right_line_x, deg=1))right_x_start = int(poly_right(max_y))right_x_end = int(poly_right(min_y))else:right_x_start, right_x_end = 0, 0  # Defaults if no lines detected# Create the filled polygon between the left and right lane lineslane_image = draw_lane_lines(image,[left_x_start, max_y, left_x_end, min_y],[right_x_start, max_y, right_x_end, min_y])return lane_image# Function to estimate distance based on bounding box size
def estimate_distance(bbox_width, bbox_height):# For simplicity, assume the distance is inversely proportional to the box size# This is a basic estimation, you may use camera calibration for more accuracyfocal_length = 1000  # Example focal length, modify based on camera setupknown_width = 2.0  # Approximate width of the car (in meters)distance = (known_width * focal_length) / bbox_width  # Basic distance estimationreturn distance# Main function to read and process video with YOLOv8
def process_video():# Load the YOLOv8 modelmodel = YOLO('weights/yolov8n.pt')# 或者加载官方模型# model = YOLO("yolov8n.pt")  # load an official model# Open the video filecap = cv2.VideoCapture('video/video.mp4')# Check if video opened successfullyif not cap.isOpened():print("Error: Unable to open video file.")return# Set the desired frame ratetarget_fps = 30frame_time = 1.0 / target_fps  # Time per frame to maintain 30fps# Resize to 720p (1280x720)cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)# Loop through each framewhile cap.isOpened():ret, frame = cap.read()if not ret:break# Resize frame to 720presized_frame = cv2.resize(frame, (1280, 720))# Run the lane detection pipelinelane_frame = pipeline(resized_frame)# Run YOLOv8 to detect cars in the current frameresults = model(resized_frame)# Process the detections from YOLOv8for result in results:boxes = result.boxesfor box in boxes:x1, y1, x2, y2 = map(int, box.xyxy[0])  # Bounding box coordinatesconf = box.conf[0]  # Confidence scorecls = int(box.cls[0])  # Class ID# Only draw bounding boxes for cars with confidence >= 0.5if model.names[cls] == 'car' and conf >= 0.5:label = f'{model.names[cls]} {conf:.2f}'# Draw the bounding boxcv2.rectangle(lane_frame, (x1, y1), (x2, y2), (0, 255, 255), 2)cv2.putText(lane_frame, label, (x1, y1 - 10),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 255), 2)# Estimate the distance of the carbbox_width = x2 - x1bbox_height = y2 - y1distance = estimate_distance(bbox_width, bbox_height)# Display the estimated distancedistance_label = f'Distance: {distance:.2f}m'cv2.putText(lane_frame, distance_label, (x1, y2 + 20),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2)# Display the resulting frame with both lane detection and car detectioncv2.imshow('Lane and Car Detection', lane_frame)# Limit the frame rate to 30fpstime.sleep(frame_time)# Break the loop when 'q' is pressedif cv2.waitKey(1) & 0xFF == ord('q'):break# Release video capture and close windowscap.release()cv2.destroyAllWindows()# Run the video processing function
process_video()

4、工作原理

4.1 车道线检测 Pipeline

车道线检测包括一下几个步骤:

Step 1: 屏蔽感兴趣区域(ROI)
只处理图像的下半部分(车道线通常是可见的)。

def region_of_interest(img, vertices):mask = np.zeros_like(img)match_mask_color = 255cv2.fillPoly(mask, vertices, match_mask_color)masked_image = cv2.bitwise_and(img, mask)return masked_image

Step 2: 使用Canny进行边缘检测
将图像转换为灰度,并应用Canny边缘检测来突出显示边缘。

gray_image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
cannyed_image = cv2.Canny(gray_image, 100, 200)

Step 3: 霍夫线变换
霍夫线变换用于检测当前车道的线段。

lines = cv2.HoughLinesP(cropped_image,rho=6,theta=np.pi / 60,threshold=160,lines=np.array([]),minLineLength=40,maxLineGap=25
)

4.2 使用YOLOv8进行车辆检测

Step 1: 加载YOLOv8模型
我们使用预训练的YOLOv8模型来检测每一帧中的汽车(或者使用官方提供的模型)。

from ultralytics import YOLO
model = YOLO('weights/yolov8n.pt')
# model = YOLO('yolov8n.pt') #官方提供的模型

Step 2: 绘制边界框
对于每一辆检测到的汽车,绘制边界框,并显示类名(汽车)和置信度分数。

for box in boxes:x1, y1, x2, y2 = map(int, box.xyxy[0])conf = box.conf[0]if model.names[cls] == 'car' and conf >= 0.5:label = f'{model.names[cls]} {conf:.2f}'cv2.rectangle(lane_frame, (x1, y1), (x2, y2), (0, 255, 255), 2)cv2.putText(lane_frame, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 255), 2)

Step 3:. 距离估计
根据边界框的大小估计到每辆检测到的汽车的距离。

def estimate_distance(bbox_width, bbox_height):focal_length = 1000  # Example focal lengthknown_width = 2.0  # Approximate width of a car (in meters)distance = (known_width * focal_length) / bbox_widthreturn distance

Step 4:. 视频处理 Pipeline
将车道检测、车辆检测和距离估计结合到一个实时视频处理pipeline中。

while cap.isOpened():ret, frame = cap.read()if not ret:breaklane_frame = pipeline(resized_frame)results = model(resized_frame)for result in results:# Draw bounding boxes and estimate distancecv2.imshow('Lane and Car Detection', lane_frame)if cv2.waitKey(1) & 0xFF == ord('q'):break

5、结果

在这里插入图片描述

  • 项目源码地址: https://github.com/CityIsBetter/Lane_Detection

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/44.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

相加交互效应函数发布—适用于逻辑回归、cox回归、glmm模型、gee模型

在统计分析中交互作用是指某因素的作用随其他因素水平变化而变化&#xff0c;两因素共同作用不等于两因素单独作用之和(相加交互作用)或之积(相乘交互作用)。相互作用的评估是尺度相关的&#xff1a;乘法或加法。乘法尺度上的相互作用意味着两次暴露的综合效应大于&#xff08;…

ECharts饼图下钻

背景 项目上需要对Echarts饼图进行功能定制&#xff0c;实现点击颜色块&#xff0c;下钻显示下一层级占比 说明 饼图实现点击下钻/面包屑返回的功能 实现 数据结构 [{name: a,value: 1,children: [...]},... ]点击下钻 // 为图表绑定点击事件&#xff08;需要在destroy…

MySQL-事务

事务特性 在关系型数据库管理系统中&#xff0c;事务必须满足 4 个特性&#xff0c;即所谓的 ACID。 原子性&#xff08;Atomicity&#xff09; 事务是一个原子操作单元&#xff0c;其对数据的修改&#xff0c;要么全都执行&#xff0c;要么全都不执行。 修改操作>修改B…

C# 元组

总目录 C# 语法总目录 C# 元组 C# 介绍元组1. 元组元素命名2. 元组的解构3. 元组的比较 总结参考链接 C# 介绍 C#主要应用于桌面应用程序开发、Web应用程序开发、移动应用程序开发、游戏开发、云和服务开发、数据库开发、科学计算、物联网&#xff08;IoT&#xff09;应用程序、…

用 Python 绘制可爱的招财猫

✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ ​​​​​ ​​​​​​​​​ ​​​​ 招财猫&#xff0c;也被称为“幸运猫”&#xff0c;是一种象征财富和好运的吉祥物&#xff0c;经常…

Java多线程

一、线程的简介: 1.普通方法调用和多线程: 2.程序、进程和线程: 在操作系统中运行的程序就是进程&#xff0c;一个进程可以有多个线程 程序是指令和数据的有序集合&#xff0c;其本身没有任何运行的含义&#xff0c;是一个静态的概念&#xff1b; 进程则是执行程序的一次执…

IP 地址与蜜罐技术

基于IP的地址的蜜罐技术是一种主动防御策略&#xff0c;它能够通过在网络上布置的一些看似正常没问题的IP地址来吸引恶意者的注意&#xff0c;将恶意者引导到预先布置好的伪装的目标之中。 如何实现蜜罐技术 当恶意攻击者在网络中四处扫描&#xff0c;寻找可入侵的目标时&…

鸿蒙面试 2025-01-09

鸿蒙分布式理念&#xff1f;&#xff08;个人认为理解就好&#xff09; 鸿蒙操作系统的分布式理念主要体现在其独特的“流转”能力和相关的分布式操作上。在鸿蒙系统中&#xff0c;“流转”是指涉多端的分布式操作&#xff0c;它打破了设备之间的界限&#xff0c;实现了多设备…

GDPU Android移动应用 重点习题集

目录 程序填空 ppt摘选 题目摘选 “就这两页ppt&#xff0c;你还背不了吗” “。。。” 打开ppt后 “Sorry咯&#xff0c;还真背不了&#x1f61c;” 更新日志 考后的更新日志 没想到重点勾了一堆&#xff0c;还愣是没考到其中的内容&#xff0c;翻了一下&#xff0c;原…

Unity3d 基于Barracuda推理库和YOLO算法实现对象检测功能

前言 近年来&#xff0c;随着AI技术的发展&#xff0c;在游戏引擎中实现和运行机器学习模型的需求也逐渐显现。Unity3d引擎官方推出深度学习推理框架–Barracuda &#xff0c;旨在帮助开发者在Unity3d中轻松地实现和运行机器学习模型&#xff0c;它的主要功能是支持在 Unity 中…

【Notepad++】Notepad++如何删除包含某个字符串所在的行

Notepad如何删除包含某个字符串所在的行 一&#xff0c;简介二&#xff0c;操作方法三&#xff0c;总结 一&#xff0c;简介 在使用beyoundcompare软件进行对比的时候&#xff0c;常常会出现一些无关紧要的地方&#xff0c;且所在行的内容是变化的&#xff0c;不方便进行比较&…

机器学习笔记合集

大家好&#xff0c;这里是好评笔记&#xff0c;公主 号&#xff1a;Goodnote。本笔记的任务是解读机器学习实践/面试过程中可能会用到的知识点&#xff0c;内容通俗易懂&#xff0c;入门、实习和校招轻松搞定。 笔记介绍 本笔记的任务是解读机器学习实践/面试过程中可能会用到…

OCR文字识别—基于PP-OCR模型实现ONNX C++推理部署

概述 PaddleOCR 是一款基于 PaddlePaddle 深度学习平台的开源 OCR 工具。PP-OCR是PaddleOCR自研的实用的超轻量OCR系统。它是一个两阶段的OCR系统&#xff0c;其中文本检测算法选用DB&#xff0c;文本识别算法选用CRNN&#xff0c;并在检测和识别模块之间添加文本方向分类器&a…

湘潭大学人机交互复习

老师没给题型也没划重点&#xff0c;随便看看复习了 什么是人机交互 人机交互&#xff08;Human-Computer Interaction&#xff0c;HCI&#xff09;是关于设计、评价和实现供人们使用的交互式计算机系统&#xff0c;并围绕相关的主要现象进行研究的学科。 人机交互研究内容 …

离线录制激光雷达数据进行建图

目前有一个2D激光雷达&#xff0c;自己控制小车运行一段时间&#xff0c;离线获取到激光雷达数据后运行如下代码进行离线建图。 roslaunch cartographer_ros demo_revo_lds.launch bag_filename:/home/firefly/AutoCar/data/rplidar_s2/2025-01-08-02-08-33.bag实际效果如下 d…

通信与网络安全管理之ISO七层模型与TCP/IP模型

一.ISO参考模型 OSI七层模型一般指开放系统互连参考模型 (Open System Interconnect 简称OSI&#xff09;是国际标准化组织(ISO)和国际电报电话咨询委员会(CCITT)联合制定的开放系统互连参考模型&#xff0c;为开放式互连信息系统提供了一种功能结构的框架。 它从低到高分别是…

Linux权限

目录 一.Linux权限的概念 二.Linux权限管理 1.文件访问者的分类 2.文件类型和访问权限 1.文件类型 2.基本权限 3.文件权限的表示方法 1.字符表示法 2.八进制表示法 4.文件权限的相关访问方法 1.chmod 2.chown 3.chgrp 4.粘滞位 三.权限总结 一.Linux权限的概念 …

UML系列之Rational Rose笔记三:活动图(泳道图)

一、新建活动图&#xff08;泳道图&#xff09; 依旧在用例视图里面&#xff0c;新建一个activity diagram&#xff1b;新建好之后&#xff0c;就可以绘制活动图了&#xff1a; 正常每个活动需要一个开始&#xff0c;点击黑点&#xff0c;然后在图中某个位置安放&#xff0c;接…

react-quill 富文本组件编写和应用

index.tsx文件 import React, { useRef, useState } from react; import { Modal, Button } from antd; import RichEditor from ./RichEditor;const AnchorTouchHistory: React.FC () > {const editorRef useRef<any>(null);const [isModalVisible, setIsModalVis…

基于mybatis-plus历史背景下的多租户平台改造

前言 别误会&#xff0c;本篇【并不是】 要用mybatis-plus自身的多租户方案&#xff1a;在表中加一个tenant_id字段来区分不同的租户数据。并不是的&#xff01; 而是在假设业务系统已经使用mybatis-plus多数据源的前提下&#xff0c;如何实现业务数据库隔开的多租户系统。 这…