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

news2024/11/19 12:34:30

本项目旨在开发一个集车道检测与物体检测功能于一体的智能视觉分析系统,利用先进的计算机视觉技术和深度学习模型,实现实时的道路场景理解和目标识别。系统主要依托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 argparse

parser = 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 = 480



net = 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 array

layers_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 = 480


if cameraFeed:intialTracbarVals = [24,55,12,100] #  #wT,hT,wB,hB
else:intialTracbarVals = [42,63,14,87]   #wT,hT,wB,hB

output_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)

        # Average
        currentCurve = lane_curve // 50
        if  int(np.sum(arrayCurve)) == 0:averageCurve = currentCurve
        else:
            averageCurve = np.sum(arrayCurve) // arrayCurve.shape[0]
        if abs(averageCurve-currentCurve) >200: arrayCurve[arrayCounter] = averageCurve
        else :arrayCurve[arrayCounter] = currentCurve
        arrayCounter +=1
        if arrayCounter >=noOfArrayValues : arrayCounter=0
        cv2.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=00
        pass

    imgFinal= drawLines(imgFinal,lane_curve)

    # Object detection 
    success, frame = cap.read()

    frame = cv2.resize(frame, (frameWidth, frameHeight), None)
    frame_id += 1
    height, width, channels = frame.shape
    # Detect image
    blob = 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 screen
    class_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 detected
                center_x = int(detection[0] * width)
                center_y = int(detection[1] * height)
                w = int(detection[2] * width)
                h = int(detection[3] * height)

                # Rectangle coordinates
                x = 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 object
                class_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_time
    fps = frame_id / elapsed_time
    cv2.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.coloradmin.cn/o/1896427.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【笔试记录】腾讯音乐 | 20230903 | cpp (更新ing)

1 完美数 1.1 题目描述 小红定义一个数为“完美数”&#xff0c;当且仅当该数仅有一个非零数字。例如 5000, 4, 1, 10, 200 都是完美数。 小红拿到了一个大小为 n&#xff08;2 < n < 2000&#xff09;的数组 a&#xff0c;她希望选择数组中的两个元素&#xff08;1 …

KEYSIGHT N1092系列,DCA-M系列采样示波器连接与自检?

KEYSIGHT N1092系列 采样示波器&#xff0c;虽然省去了屏幕和操作系统&#xff0c;但根据不同的型号&#xff0c;可以配备不同数量的光口和电口&#xff0c;满足各种测试需求。本次介绍的具体型号为N1092D&#xff0c;它拥有4个光口&#xff0c;能够进行多种测试。 测试步骤详解…

14-26 剑和侠客 – 预训练模型三部曲3 – 机器人时代来临

概述 在第 1 部分和第 2 部分中&#xff0c;我们讨论了适用于文本和图像任务的预训练模型&#xff0c;并探索了当今常用的模型。我们分析了这些模型的架构以及如何将它们用于特定任务。实现 AGI 所需的两个主要支柱是语言理解和机器的视觉能力。有许多任务与这两种能力有关。 …

日本最新型高达式巨型机器人承担铁路维护任务

日本有制造现实生活中的高达式巨型机器人的历史&#xff0c;但它们往往是用于娱乐目的&#xff0c;而不是实际应用。不过&#xff0c;日本刚刚开始使用一个 40 英尺高的人形机器人来维护铁路线。 大约两年前&#xff0c;西日本铁路公司&#xff08;JR 西日本&#xff09;制造了…

长难句打卡6.26

Too often we believe that a new job, bigger house or better car will be the magic silver bullet that will allow us to finally be content, but the reality is these things have very little lasting impact on our happiness levels. magic silver bullet 灵丹妙药 …

(三)共享模型之管程

线程安全问题 案例 两个线程对初始值为 0 的静态变量一个做自增&#xff0c;一个做自减&#xff0c;各做 5000 次&#xff0c;结果是 0 吗&#xff1f; Slf4j(topic "c.ThreadSafe") public class ThreadSafe {public static int counter 0;public static void …

NFT音乐版权系统的技术难点

NFT音乐版权系统是指利用区块链技术和NFT技术来管理和交易音乐版权的系统。该系统涉及多项技术&#xff0c;其开发和应用存在以下技术难点。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1. 音乐作品的数字版权确权 音乐作品的数字…

《向量数据库指南》——Milvus Cloud查询增强如何提升 RAG Pipeline 效果?

查询增强 1.假设性问题 这一方法首先使用LLM为每一条文档块生成一些假设问题,这些文档块可以回答与之对应的假设问题。在RAG阶段,进行一个query-to-query的搜索,先搜索到相关的假设问题,然后找到对应的文档块,再通过它们生成最后的回答。 这里的query-to-query指的是embed…

7月开强化,考研数学保底110分真的很难吗?

七月开始强化是正常时间 不要因为进度而感到焦虑&#xff0c;因为进度是很主观的因素&#xff0c;无法衡量学习效果&#xff01;所以&#xff0c;不要和比人比进度&#xff0c;也不要赶进度&#xff0c;一步一个脚印&#xff0c;踏踏实实的学习才是王道&#xff01; 虽然我不…

MicroCap声学仿真介绍(一)

MicroCap是一款基于电路分析的仿真软件&#xff0c;基于集总参数的电力声的转换&#xff0c;我们可以用这个软件完成常用的声学仿真工作。目前这个软件已经开源了&#xff0c;免费使用&#xff0c;最新版已经到MC12&#xff0c;但里面不自带声学库&#xff0c;后来找到了MC8&am…

react v18 less使用(craco)

方案一、弹出配置&#xff08;不推荐&#xff09; 安装依赖&#xff1a;yarn add less less-loader 首先 执行 yarn eject 弹出配置项文件&#xff08;注意&#xff1a;弹出配置不可逆&#xff01;&#xff09; 在 config 文件夹中 找到 webpack.config.js&#xff0c;在如图…

Vue 详情实战涉及从项目初始化到功能实现、测试及部署的整个过程

本人详解 作者:王文峰,参加过 CSDN 2020年度博客之星,《Java王大师王天师》 公众号:JAVA开发王大师,专注于天道酬勤的 Java 开发问题中国国学、传统文化和代码爱好者的程序人生,期待你的关注和支持!本人外号:神秘小峯 山峯 转载说明:务必注明来源(注明:作者:王文峰…

视频提取字幕怎么弄?5个快速获取视频字幕的方法

在忙碌而又充满活力的生活中&#xff0c;我们常常在通勤路上和午休间隙通过视频来获取信息和放松心情。 但有时候&#xff0c;我们想把视频里那些令人难忘的瞬间或关键信息保存下来&#xff0c;方便以后回顾或者分享。然而&#xff0c;手动摘录不仅费时&#xff0c;还容易漏掉…

BugkuCTF-Crypto(1-5)

题&#xff1a;抄错的字符 题目作者: Aman 题目描述:老师让小明抄写一段话&#xff0c;结果粗心的小明把部分数字抄成了字母&#xff0c;还因为强迫症把所有字母都换成大写。你能帮小明恢复并解开答案吗&#xff1a;QWIHBLGZZXJSXZNVBZW 分析&#xff1a; 数字和字符可能的转…

数据库管理-第217期 Oracle的高可用-02(20240704)

数据库管理217期 2024-07-04 数据库管理-第217期 Oracle的高可用-02&#xff08;20240704&#xff09;1 GDS简介2 GDS架构2.1 全局数据服务池2.2 全局数据服务域2.3 全局服务管理2.4 全局数据服务目录2.5 Oracle通知服务 3 GDS简图3.1 负载均衡3.2 只读服务失败转移3.3 多主复制…

7.1 动态规划背包问题综述

动态规划中的背包问题是一类经典的优化问题&#xff0c;主要涉及到在给定的限制条件下&#xff08;如背包容量&#xff09;&#xff0c;如何选择物品集合以达到某种最优目标&#xff08;如价值最大&#xff09;。这类问题通常可以细分为几种类型&#xff0c;包括0-1背包问题、完…

Android的图书交易APP-计算机毕业设计源码25753

摘 要 在数字化与移动互联网迅猛发展的今天&#xff0c;人们对于图书的需求与消费方式也在悄然改变。为了满足广大读者对图书的热爱与追求&#xff0c;我们倾力打造了一款基于Android平台的图书交易APP。这款APP不仅汇聚了海量的图书资源&#xff0c;提供了便捷的交易平台&…

.Net Core + DDD基础分层

基础设施层 基础设施层使用的相关知识&#xff1a;Code First &#xff0c;EF Core&#xff0c;Autofac依赖注入&#xff0c;仓储模式的实现接口&#xff0c;领域服务的实现接口&#xff0c;缓存&#xff0c;以及各种基础工具类 一&#xff0c;Code First&#xff1a;使用Cod…

大学生竞赛管理系统-计算机毕业设计源码37276

大学生竞赛管理系统的设计与实现 摘 要 随着教育信息化的不断发展&#xff0c;大学生竞赛已成为高校教育的重要组成部分。传统的竞赛组织和管理方式存在着诸多问题&#xff0c;如信息不透明、效率低下、管理不便等。为了解决这些问题&#xff0c;提高竞赛组织和管理效率&#x…

新书速览|UML 2.5基础、建模与设计实践

《UML 2.5基础、建模与设计实战》 本书内容 UML是以面向对象图形的方式来描述任何类型的系统&#xff0c;应用领域非常广泛&#xff0c;其中常用的是建立软件系统的模型。《UML 2.5基础、建模与设计实践》基于draw.io开源免费软件&#xff0c;全面讲解UML 2.5的基本概念和建模…