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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CentOS7.9下yum升级Apache HTTP Server2.4.6到2.4.60

1、CentOS7.9系统默认的Apache版本 在CentOS7.9上,如果使用yum安装Apache HTTP Server是最多到2.4.6版本的,这是因为el7下官方仓库的最高版本就是2.4.6,证据如下: $ yum info httpd ...... Installed Packages Name : ht…

Jetpack Compose实战教程(五)

Jetpack Compose实战教程(五) 第五章 如何在Compose UI中使用基于命令式UI的自定义View 文章目录 Jetpack Compose实战教程(五)一、前言二、本章目标三、开始编码3.1 先让自定义控件能跑起来3.2给自定义控件使用compose的方式赋值…

【设计模式】工厂模式(定义 | 特点 | Demo入门讲解)

文章目录 定义简单工厂模式案例 | 代码Phone顶层接口设计Meizu品牌类Xiaomi品牌类PhoneFactory工厂类Customer 消费者类 工厂方法模式案例 | 代码PhoneFactory工厂类 Java高级特性---工厂模式与反射的高阶玩法方案:反射工厂模式 总结 其实工厂模式就是用一个代理类帮…

Java项目:基于SSM框架实现的学生公寓管理中心系统【ssm+B/S架构+源码+数据库+毕业论文】

一、项目简介 本项目是一套基于SSM框架实现的学生公寓管理中心系统 包含:项目源码、数据库脚本等,该项目附带全部源码可作为毕设使用。 项目都经过严格调试,eclipse或者idea 确保可以运行! 该系统功能完善、界面美观、操作简单、…

【CentOS 7.6】Linux版本 portainer本地镜像导入docker安装配置教程,不需要魔法拉取!(找不着镜像的来看我)

吐槽 我本来根本不想写这篇博客,但我很不解也有点生气,CSDN这么大没有人把现在需要魔法才能拉取的镜像放上来。 你们都不放,根本不方便。我来上传资源。 portainer-ce-latest.tar Linux/amd64 镜像下载地址: 链接:h…

加法器的基本操作

基本单元 与门(AND) 全1为1,有0为0 或门(OR) 全0为0,有1为1 非门(NOT) 为1则0,为0则1 异或门(XOR) 两个输入端,相同为0,不同为1 与非门(NADD) 全1为0,有0为1 或非门(NOR) 全0为1,有1为0。刚…

H5 Canvas实现转盘效果,控制指定数字

效果图 实现思路&#xff1a; 用Canvas画圆&#xff0c;然后再画扇形&#xff0c;然后中奖的开始用一张图片代替&#xff0c;点击的时候触发转动效果。 实现代码&#xff1a; <!DOCTYPE html> <html> <head><meta charset"utf-8"><tit…

UNDO 表空间使用率高 active段占用高 无对应事务执行

UNDO表空间使用率告警&#xff0c;查看占用情况 active段占比很高 select tablespace_name,status,sum(bytes/1024/1024) mb from dba_undo_extents group by tablespace_name,status;不同状态的含义&#xff1a;**ACTIVE **&#xff1a;有活动事务在使用 Undo&#xff0c;这…

【JavaSE】数据类型与变量

目录 1. 字面常量 2. 数据类型 3. 变量 3.1 变量概念 3.2 语法格式 3.3 整型变量 3.3.1 整型变量 3.3.2 长整型变量 3.3.3 短整型变量 3.3.4 字节型变量 3.4 浮点型变量 3.4.1 双精度浮点型 3.4.2 单精度浮点型 3.5 字符型变量 3.6 布尔型变量 3.7 类型转换 3…

WEB安全-靶场

1 需求 2 语法 3 示例 男黑客|在线渗透测试靶场|网络安全培训基地|男黑客安全网 4 参考资料

windows 7 安装IPP协议,支持Internet打印

1 windows 7 安装IPP协议,支持Internet打印 #控制面板--打开或关闭Windows功能 3 复制Printers 文件夹 到 c:\inetpub\wwwroot\,复制msw3prt.dll到c:\windows\system32\ 4 打开IIs管理器 #报错:模块列表中不存在此处理程序所需的指定模块。如果您添加脚本映射处理程序映射&…

【力扣】数组中的第K个最大元素

一、题目描述 给定整数数组 nums 和整数 k&#xff0c;请返回数组中第 k 个最大的元素。 请注意&#xff0c;你需要找的是数组排序后的第 k 个最大的元素&#xff0c;而不是第 k 个不同的元素。 你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例 1: 输入: [3,2,1,5,…

记一次EasyExcel的错误使用导致的频繁FullGC

记一次EasyExcel的错误使用导致的频繁FullGC 一、背景描述二、场景复现三、原因分析四、解决方案五、思考复盘 一、背景描述 繁忙的校招结束了&#xff0c;美好的大学四年也结束了&#xff0c;作者也有10个月没有更新了。拿到心仪的offer之后也开始了苦B的打工生活。 最近接到…

汽车信息安全--欧盟汽车法规

目录 General regulation 信息安全法规 R155《网络安全及网络安全管理系统》解析 R156《软件升级与软件升级管理系统》解析 General regulation 欧洲的汽车行业受到一系列法律法规的约束&#xff0c;包括 各个方面包括&#xff1a; 1.安全要求&#xff1a;《通用安全条例&a…

10.x86游戏实战-汇编指令lea

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 工具下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd6tw3 提…

SpringBoot之内容协商

现象演示 假设有一个需求是根据终端的不同&#xff0c;返回不同形式的数据&#xff0c;比如 PC 端需要以 HTML 格式返回数据&#xff0c;APP、小程序端需要以 JSON 格式返回数据。这时我们是 coding 几个相似的接口&#xff1f;还是在一个接口里面做复杂判断处理&#xff1f;两…

测试驱动开发(TDD)方法详解

目录 前言1. 什么是测试驱动开发1.1 TDD的基本原则1.2 TDD的优势 2. 测试驱动开发的流程2.1 编写测试2.2 运行测试2.3 编写实现代码2.4 重构代码 3. 常用工具和框架3.1 单元测试框架3.2 Mock框架3.3 集成工具 4. TDD在实际项目中的应用4.1 应用场景4.2 面临的挑战4.3 最佳实践 …

计算机的错误计算(二十二)

摘要 计算机的错误计算&#xff08;十九&#xff09;展示了计算机的一个错误计算&#xff1a;本应该为 0的算式的结果不为0. 那么&#xff0c;增加计算精度&#xff0c;能确定是0吗&#xff1f;不一定。 计算机的错误计算&#xff08;十九&#xff09;展示了计算机对 的错误计…

liunx清理服务器内存和日志

1、查看服务器磁盘占用情况 # 查看磁盘占用大小 df -h 2、删除data文件夹下面的日志 3、查看每个服务下面的日志输出文件&#xff0c;过大就先停掉服务再删除out文件再重启服务 4、先进入想删除输入日志的服务文件夹下&#xff0c;查看服务进程&#xff0c;杀掉进程&#xff…

代码随想录算法训练营第二天|【数组】209.长度最小的子数组

题目 给定一个含有 n 个正整数的数组和一个正整数 s &#xff0c;找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组&#xff0c;并返回其长度。如果不存在符合条件的子数组&#xff0c;返回 0。 示例&#xff1a; 输入&#xff1a;s 7, nums [2,3,1,2,4,3] 输出&#…