使用 OpenCV 和 Python 进行车道检测和物体检测(YOLO)

本项目旨在开发一个集车道检测与物体检测功能于一体的智能视觉分析系统,利用先进的计算机视觉技术和深度学习模型,实现实时的道路场景理解和目标识别。系统主要依托OpenCV这一强大的计算机视觉库,以及Python作为编程语言,融合了车道检测算法和YOLO(You Only Look Once)物体检测算法,以期达到高效、精准的视觉分析效果。

1. 车道检测

车道检测部分主要采用基于图像处理的技术,具体步骤包括:

  • 预处理:对输入的图像进行灰度化、高斯模糊、Canny边缘检测等操作,以增强图像的对比度和减少噪声干扰。

  • 兴趣区域提取:通过多边形掩模,只保留包含车道线的区域,忽略无关背景。

  • 霍夫变换:利用霍夫直线变换检测车道线,将边缘图像转换到参数空间,寻找直线的参数。

  • 后处理:对检测到的车道线进行拟合和平滑,确保车道线的连续性和准确性。

2. 物体检测(YOLO)

YOLO算法是一种实时的目标检测框架,其核心特点是在一次前向传播中同时预测物体的位置和类别,大幅提高了检测速度。本项目中,我们采用YOLOv4或YOLOv5作为基础模型,针对特定场景进行微调和优化,以提高检测精度和泛化能力。

实现流程

  1. 数据准备:收集大量的道路场景图像和视频,包括不同天气、光照条件下的样本,进行标注,构建训练数据集。

  2. 模型训练:使用标注好的数据集,训练车道检测模型和YOLO模型,调整超参数,优化模型性能。

  3. 系统集成:将车道检测和物体检测两个子系统整合到一起,设计合理的输入输出接口,确保两者的无缝协作。

  4. 测试与评估:在多种场景下测试系统性能,包括但不限于城市街道、高速公路、夜间环境等,评估检测精度、实时性和稳定性。

  5. 部署与优化:根据实际应用需求,将系统部署到目标平台,如自动驾驶车辆、监控系统等,并持续收集反馈,进行迭代优化。

应用前景

本项目成果可广泛应用于智能交通、自动驾驶、安防监控等领域,为实现更加安全、高效的交通系统提供技术支持。例如,在自动驾驶车辆中,车道检测与物体检测的结合可以帮助车辆实时理解周围环境,做出准确的决策;在城市监控系统中,则能辅助警察和安保人员快速识别异常情况,提升公共安全水平。

结语

通过融合车道检测与物体检测两大核心技术,本项目致力于打造一个全面、智能的视觉分析系统,推动计算机视觉技术在实际应用中的创新与发展。

关键代码部分

import numpy as np
import cv2
from utils import *
import os
import time
import argparseparser = argparse.ArgumentParser()
parser.add_argument('--model_cfg', type = str, default = '',help = 'Path to config file')
parser.add_argument('--model_weights', type=str,default='',help='path to weights of model')
parser.add_argument('--video', type=str, default='',help='path to video file')
parser.add_argument('--src', type=int, default=0,help='source of the camera')
parser.add_argument('--output_dir', type=str, default='',help='path to the output directory')
args = parser.parse_args()# print the arguments
print('----- info -----')
print('[i] The config file: ', args.model_cfg)
print('[i] The weights of model file: ', args.model_weights)
print('[i] Path to video file: ', args.video)
print('###########################################################\n')
frameWidth= 640
frameHeight = 480net = cv2.dnn.readNet(args.model_weights, args.model_cfg)
classes = []
with open("coco.names", "r") as f:classes = [line.strip() for line in f.readlines()] # we put the names in to an arraylayers_names = net.getLayerNames()
output_layers = [layers_names[i[0] -1] for i in net.getUnconnectedOutLayers()]
colors = np.random.uniform(0, 255, size = (len(classes), 3))font = cv2.FONT_HERSHEY_PLAIN
frame_id = 0
cameraFeed= False
#videoPath = 'road_car_view.mp4'
cameraNo= 1
#frameWidth= 640
#frameHeight = 480if cameraFeed:intialTracbarVals = [24,55,12,100] #  #wT,hT,wB,hB
else:intialTracbarVals = [42,63,14,87]   #wT,hT,wB,hBoutput_file = ''
if cameraFeed:cap = cv2.VideoCapture(cameraNo)cap.set(3, frameWidth)cap.set(4, frameHeight)
else:cap = cv2.VideoCapture(args.video)output_file = args.video[:-4].rsplit('/')[-1] + '_Detection.avi'
count=0
noOfArrayValues =10
#global arrayCurve, arrayCounter
arrayCounter=0
arrayCurve = np.zeros([noOfArrayValues])
myVals=[]
initializeTrackbars(intialTracbarVals)#fourcc = cv2.VideoWriter_fourcc(*'XVID')
#video_writer = cv2.VideoWriter('output.avi', fourcc, 20.0, (640,480))
video_writer = cv2.VideoWriter('output2.avi', cv2.VideoWriter_fourcc(*'XVID'), cap.get(cv2.CAP_PROP_FPS), (2 * frameWidth,frameHeight))
starting_time = time.time()
while True:success, img = cap.read()if not success:print('[i] ==> Done processing!!!')print('[i] ==> Output file is stored at', os.path.join(args.output_dir, output_file))cv2.waitKey(1000)break#img = cv2.imread('test3.jpg')if cameraFeed== False:img = cv2.resize(img, (frameWidth, frameHeight), None)imgWarpPoints = img.copy()imgFinal = img.copy()imgCanny = img.copy()imgUndis = undistort(img)imgThres,imgCanny,imgColor = thresholding(imgUndis)src = valTrackbars()imgWarp = perspective_warp(imgThres, dst_size=(frameWidth, frameHeight), src=src)imgWarpPoints = drawPoints(imgWarpPoints, src)imgSliding, curves, lanes, ploty = sliding_window(imgWarp, draw_windows=True)try:curverad =get_curve(imgFinal, curves[0], curves[1])lane_curve = np.mean([curverad[0], curverad[1]])imgFinal = draw_lanes(img, curves[0], curves[1],frameWidth,frameHeight,src=src)# AveragecurrentCurve = lane_curve // 50if  int(np.sum(arrayCurve)) == 0:averageCurve = currentCurveelse:averageCurve = np.sum(arrayCurve) // arrayCurve.shape[0]if abs(averageCurve-currentCurve) >200: arrayCurve[arrayCounter] = averageCurveelse :arrayCurve[arrayCounter] = currentCurvearrayCounter +=1if arrayCounter >=noOfArrayValues : arrayCounter=0cv2.putText(imgFinal, str(int(averageCurve)), (frameWidth//2-70, 70), cv2.FONT_HERSHEY_DUPLEX, 1.75, (0, 0, 255), 2, cv2.LINE_AA)except:lane_curve=00passimgFinal= drawLines(imgFinal,lane_curve)# Object detection success, frame = cap.read()frame = cv2.resize(frame, (frameWidth, frameHeight), None)frame_id += 1height, width, channels = frame.shape# Detect imageblob = cv2.dnn.blobFromImage(frame, 0.00392, (320, 320), (0,0,0), swapRB = True, crop = False)net.setInput(blob)start = time.time()outs = net.forward(output_layers)# Showing informations on the screenclass_ids = []confidences = []boxes = []for out in outs:for detection in out:scores = detection[5:]class_id = np.argmax(scores)confidence = scores[class_id]if confidence > 0.5:#Object detectedcenter_x = int(detection[0] * width)center_y = int(detection[1] * height)w = int(detection[2] * width)h = int(detection[3] * height)# Rectangle coordinatesx = int(center_x - w / 2)y = int(center_y -h / 2)#cv2.rectangle(img, (x,y), (x+w, y+h), (0, 255, 0))boxes.append([x, y, w, h])confidences.append(float(confidence))# Name of the objectclass_ids.append(class_id)indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.3)for i in range(len(boxes)):if i in indexes:x, y, w, h = boxes[i]label = "{}: {:.2f}%".format(classes[class_ids[i]], confidences[i]*100)color = colors[i]cv2.rectangle(frame, (x,y), (x+w, y+h), color, 2)cv2.putText(frame, label, (x,y+10), font, 2, color, 2)elapsed_time = time.time() - starting_timefps = frame_id / elapsed_timecv2.putText(frame, "FPS:" + str(fps), (10,30), font, 2, (0, 0, 0), 1)imgBlank = np.zeros_like(img)imgStacked = stackImages(0.7, ([imgUndis,frame],[imgColor, imgCanny],[imgWarp,imgSliding]))#final_frame = cv2.hconcat((frame,imgCanny))#video_writer.write(final_frame)#cv2.imshow('frame',final_frame)cv2.imshow("Image", frame)cv2.imshow("PipeLine",imgStacked)cv2.imshow("Result", imgFinal)

识别道路边界的过程,即道路检测管道,主要包括以下步骤:

  1. 相机校准矩阵计算:首先,使用OpenCV库中的cv2.findChessboardCorners()函数计算相机的校准矩阵,以消除由镜头产生的畸变。这一校准步骤确保了车道检测算法能够适应不同类型的相机,提高算法的通用性。校准后,将校准矩阵应用于原始图像,进行畸变校正。

  2. 图像边缘检测与阈值处理:接着,通过一组基于梯度和颜色的阈值处理技术,使用cv2.Sobelcv2.cvtColor函数检测图像中的边缘,生成二值化的边缘图像。这一步骤有助于突出图像中的车道线条,为后续的车道边界识别奠定基础。

  3. 透视变换:为了更方便地提取车道边界,接下来会对处理后的图像进行透视变换,将其转换为鸟瞰视角。这种变换使得车道边界在图像中呈现出更为直观和易于识别的形式。

  4. 车道像素扫描与拟合:在鸟瞰图的基础上,系统会扫描整个图像,寻找属于车道边界的像素点。找到足够的像素点后,通过曲线拟合算法将它们拟合成车道边界。之后,再将检测到的车道边界反向映射回原始图像中,实现车道的可视化标识。

  5. 道路属性估算:最后,系统还会估算一些重要的道路属性,比如道路的曲率以及车辆在车道内的相对位置。这些信息对于自动驾驶车辆来说至关重要,能够帮助车辆更好地理解自身在道路上的位置和方向。

整个过程的快照可以这样描述:从原始图像开始,经过一系列精心设计的图像处理步骤,最终在图像中标记出清晰的车道边界,并提供关于道路状况的关键信息。这一系列操作构成了一个高效、准确的道路边界识别系统,是实现自动驾驶和智能交通系统的重要组成部分。

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

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

相关文章

Golang | Leetcode Golang题解之第206题反转链表

题目: 题解: func reverseList(head *ListNode) *ListNode {if head nil || head.Next nil {return head}newHead : reverseList(head.Next)head.Next.Next headhead.Next nilreturn newHead }

24西安电子科技大学马克思主义学院—考研录取情况

01、马克思主义学院各个方向 02、24马克思主义学院近三年复试分数线对比 PS:马院24年院线相对于23年院线增加15分,反映了大家对于马克思主义理论学习与研究的热情高涨,也彰显了学院在人才培养、学科建设及学术研究等方面的不断进步与成就。 6…

UE4_材质_材质节点_Fresnel

学习笔记,不喜勿喷,侵权立删,祝愿生活越来越好! 一、问题导入 在创建电影或过场动画时,你常常需要想办法更好地突显角色或场景的轮廓。这时你需要用到一种光照技术,称为边沿光照或边缘光照,它的…

爬虫笔记19——代理IP的使用

访问网站时IP被阻止 有些网站会设置特定规则来限制用户的访问,例如频率限制、单一账户多次登录等。 网站为了保护自身安全和用户体验,会设置防御机制,将涉嫌恶意行为的IP地址加入黑名单并屏蔽访问。如果用户在使用网站时违反了这些规则&…

elementPlus表格二次封装

为何要对element-plus表格进行二次封装? 我们正常在开发项目中,表格的风格是一致的,但是表格或多或少会有些不同,有些是需要分页,有些是按钮功能不同,有些又需要加Tag,或者对时间进行格式化等。…

高阶算法班从入门到精通之路课程

本课程旨在帮助学员深入理解算法与数据结构的核心概念,从而掌握高级算法设计与分析技能。每集课程内容精心设计,涵盖了常用数据结构、经典算法及其应用场景等方面的深度讲解,同时通过大量实例演练,帮助学员提升解决实际编程难题的…

Vue2基础

目录 一、初识Vue 二、Vue模板语法({{}} / v-bind) 三、数据绑定(v-model) 四、el与data的两种写法 五、MVVM模型 六、数据代理 1、Object.defineProperty 2、Vue中的数据代理 七、事件处理(v-on: / ) 1、事件的基本使用 2、事件修饰符 3、键盘事件 4、总结 八、计…

如何在Qt使用uchardet库

如何在 Qt 中使用 uchardet 库 文章目录 如何在 Qt 中使用 uchardet 库一、简介二、uchardet库的下载三、在Qt中直接调用四、编译成库文件后调用4.1 编译工具下载4.2 uchardet源码编译4.3 测试编译文件4.4 Qt中使用 五、一些小问题5.1 测试文件存在的问题5.2 uchardet库相关 六…

【启明智显分享】乐鑫HMI方案2.8寸触摸串口屏应用于太阳能控制器

前言 太阳能作为一种无尽的、可再生的能源,在现代社会的能源结构中占据着日益重要的地位。而在太阳能应用系统中,有一种设备是不可或缺的,那就是太阳能控制器。太阳能控制器在太阳能系统中起着至关重要的作用,它保证系统的安全和…

uniapp 数据父传子

文章目录 可能出现的问题 在uni-app中,父组件向子组件传递数据主要通过属性绑定的方式实现。这里提供一个简单的示例来说明如何进行父传子的数据传递: 父组件 准备数据: 在父组件的data中定义要传递的数据。 export default {data() {return {parentMe…

Spring解耦合分析和总结

在我们的日常开发中,创建对象的操作随处可见以至于对其十分熟悉的同时又感觉十分繁琐,每次需要对象都需要亲手将其new出来,甚至某些情况下由于坏编程习惯还会造成对象无法被回收,这是相当糟糕的。但更为严重的是,我们一…

Java+前后端分离架构+ MySQL8.0.36产科信息管理系统 产科电子病历系统源码

Java前后端分离架构 MySQL8.0.36产科信息管理系统 产科电子病历系统源码 产科信息管理系统—住院管理 数字化产科住院管理是现代医院管理中的重要组成部分,它利用数字化技术优化住院流程,提升医疗服务质量和效率。以下是对数字化产科住院管理的详细阐述…

Keepalived+HAProxy 集群及虚IP切换实践

1、软件介绍 ①Keepalived keepalive是一个用c语言编写的路由软件,这个项目的主要目标是为Linux系统和基于Linux的基础设施提供简单而健壮的负载平衡和高可用性设施。负载均衡框架依赖于众所周知且广泛使用的Linux Virtual Server (IPVS)内核模块提供第4层负载均衡…

【音视频 | RTSP】RTSP协议详解 及 抓包例子解析

😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀 🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C、数据结构、音视频🍭 🤣本文内容🤣&a…

maven-surefire-report-plugin插件生成测试报告

目录 官网 pom.xml配置 测试类 执行测试结果 修改测试类 pom文件更改配置maven-jxr-plugin xref xref-test ​Source Xref​ ​Test Source Xref​ 再此验证 有凭(有理)有据 官网 Maven Surefire Report Plugin – Showing Only Fail…

2024 年第十四届 APMCM 亚太地区大学生数学建模竞赛B题超详细解题思路+数据预处理问题一代码分享

B题 洪水灾害的数据分析与预测 亚太中文赛事本次报名队伍约3000队,竞赛规模体量大致相当于2024年认证杯,1/3个妈杯,1/10个国赛。赛题难度大致相当于0.6个国赛,0.8个妈杯。该比例仅供大家参考。 本次竞赛赛题难度A:B:C3:1:4&…

Java数据结构-树的面试题

目录 一.谈谈树的种类 二.红黑树如何实现 三.二叉树的题目 1.求一个二叉树的高度,有两种方法。 2.寻找二叉搜索树当中第K大的值 3、查找与根节点距离K的节点 4.二叉树两个结点的公共最近公共祖先 本专栏全是博主自己收集的面试题,仅可参考&#xf…

pandas,dataframe使用笔记

目录 新建一个dataframe不带列名带列名 dataframe添加一行内容查看dataframe某列的数据类型新建dataframe时设置了列名,则数据类型为object dataframe的保存保存为csv文件保存为excel文件 dataframe属于pandas 新建一个dataframe 不带列名 df pd.DataFrame() 带…

gda动态调试-cnblog

忽的发现gda有动态调试功能 动态监听返回值 框柱指定方法,选择调试方法,gda会自动监听函数的返回值,例如 自定义frida脚本 gda会自动生成hook该函数的frida脚本

SpringBoot学习06-[SpringBoot与AOP、SpringBoot自定义starter]

SpringBoot自定义starter SpringBoot与AOPSpringBoot集成Mybatis-整合druid在不使用启动器的情况下,手动写配置类进行整合使用启动器的情况下,进行整合 SpringBoot启动原理源码解析创建SpringApplication初始化SpringApplication总结 启动 SpringBoot自定义Starter定…