使用 Python 和 OpenCV 进行实时目标检测的详解

        使用到的模型文件我已经上传了,但是不知道能否通过审核,无法通过审核的话,就只能 靠大家自己发挥实力了,^_^

目录

简介

代码介绍

代码拆解讲解

1.首先,让我们导入需要用到的库:

2.然后,设置两个阈值:conf_threshold 和 nms_threshold,以及图片的宽度和高度:

3.接下来,我们加载预训练的 YOLOv3 模型,并加载识别的类名:

4.然后,我们创建一个颜色列表,以在最后的目标检测结果中为不同的类别绘制不同的颜色:

5.下一步,我们定义两个函数 fetch_frame 和 process_frame

6.在主循环中,我们使用 ThreadPoolExecutor 实现了并行处理读取帧和模型推理的操作。

7.退出程序

总体代码

效果展示

​编辑

使用GPU说明

如何操作

1.在读取模型时启用 CUDA:

2.其它代码不需要做太多修改:

总结        


简介

        这段程序是一个Python脚本,它使用了OpenCV库和预训练的YOLOv3模型来实现实时视频流的目标检测。它首先从摄像头捕获视频流,并使用线程池处理每一帧图像。在每一帧中,程序都会检测和识别不同的对象,并用不同的颜色显示结果。使用了非极大值抑制技术删除重复的检测框,并利用了并发处理技术以提高性能。最后,他还显示了每秒处理的帧数(FPS)。我们可以通过按'q'键来结束程序。这个程序展示了一种有效的使用深度学习模型进行实时视觉任务的方法。        


代码介绍

        这段代码是使用OpenCV和Python编写的,主要用于实时视频流处理和目标检测。代码的核心是使用训练好的YOLOv3模型来识别和定位视频帧中的对象。下面是对整个流程的详细解释:

  1. 导入库:首先,导入所需的库,包括cv2(OpenCV),numpy(用于科学计算),time(时间管理),以及concurrent.futures(用于并发执行)。

  2. 初始化参数:设置检测参数,包括置信度阈值(用于过滤掉那些置信度低于阈值的检测结果),非极大值抑制(NMS)阈值(用于去除重复的检测框),以及输入图像的宽和高。

  3. 加载模型和类别:通过使用cv2.dnn.readNet加载预训练的YOLOv3模型,并从coco.names文件中加载可以识别的类名列表。

  4. 颜色列表:为每个可识别的类别创建一个随机颜色列表,这用于在检测到的对象周围绘制彩色的边界框。

  5. 视频捕获:打开摄像头进行视频流的捕获。

  6. 多线程处理:初始化ThreadPoolExecutor以并发执行多个任务。这里定义了两个函数fetch_frameprocess_framefetch_frame用于从视频流中获取一帧图像,而process_frame则用于处理图像并执行目标检测。

  7. 目标检测流程

    • 转换输入帧:将输入帧转换为模型所需要的格式(blob),包括缩放、颜色空间转换等。
    • 执行检测:调用神经网络模型执行前向传播,获取检测结果。
    • 过滤结果:根据置信度阈值和NMS阈值过滤掉一部分检测结果,消除低置信度以及重复的检测框。
    • 绘制边界框和类别标签:在原图上绘制检测到的对象的边界框,并显示类别名称和置信度。
  8. 显示结果:在屏幕上实时显示处理后的视频帧,并计算显示FPS(每秒帧数)。

  9. 程序退出:等待我们按q键退出,并在退出前释放资源,包括摄像头和窗口。

        这段代码的设计利用了异步处理技术(通过ThreadPoolExecutor)来提高处理视频流的效率,使得帧的捕获和处理能够并行执行,从而尽可能提高FPS。

        为什么这样做,主要是我的电脑没有独立GPU,所以,呃,只能动点这中方法了,但是说实话并没有什么实质性的提升,难受了。


代码拆解讲解

        我们将使用预训练的 YOLOv3 模型进行目标检测,并使用 Python 的 concurrent.futures 库来并行处理视频帧的读取和模型推理,以优化程序的执行速度。

        感谢YOLO,虽然现在已经发展到v8了,但是我们这里使用v3还是足够了。

1.首先,让我们导入需要用到的库:

import cv2
import numpy as np
import time
from concurrent.futures import ThreadPoolExecutor

2.然后,设置两个阈值:conf_threshold 和 nms_threshold,以及图片的宽度和高度:

conf_threshold = 0.5
nms_threshold = 0.4
Width = 416
Height = 416

3.接下来,我们加载预训练的 YOLOv3 模型,并加载识别的类名:

net = cv2.dnn.readNet('../needFiles/yolov3.weights', '../needFiles/yolov3.cfg')
with open('../needFiles/coco.names', 'r') as f:classes = f.read().strip().split('\n')

4.然后,我们创建一个颜色列表,以在最后的目标检测结果中为不同的类别绘制不同的颜色:

color_list = np.random.uniform(0, 255, size=(len(classes), 3))

5.下一步,我们定义两个函数 fetch_frame 和 process_frame

        fetch_frame 用于从视频对象读取一帧;而 process_frame 则将读取到的帧输入到 YOLOv3 模型中,然后处理获得的输出结果,并在帧上绘制物体检测结果:

def fetch_frame(cap):...
def process_frame(frame):...

6.在主循环中,我们使用 ThreadPoolExecutor 实现了并行处理读取帧和模型推理的操作。

        这样可以使读取下一帧的操作和模型推理操作同时进行,从而显著地加快了处理速度:

executor = ThreadPoolExecutor(max_workers=2)
frame_future = executor.submit(fetch_frame, cap)while True:...ret, frame, height, width, channels = frame_future.result()frame_future = executor.submit(fetch_frame, cap)processed_frame = executor.submit(process_frame, frame).result()...

7.退出程序

        在这段代码的最后,如果你按下 q 键退出主循环,视频读取对象将会被释放,所有的窗口也将被销毁:

if cv2.waitKey(1) & 0xFF == ord('q'):break
...
cap.release()
cv2.destroyAllWindows()

总体代码

# 导入必要的库
import cv2
import numpy as np
import time
from concurrent.futures import ThreadPoolExecutor# 设置置信度阈值和非极大值抑制(NMS)阈值
conf_threshold = 0.5
nms_threshold = 0.4
Width = 416
Height = 416# 加载预训练的 YOLOv3 模型
net = cv2.dnn.readNet('../needFiles/yolov3.weights', '../needFiles/yolov3.cfg')# 加载可识别的类名
with open('../needFiles/coco.names', 'r') as f:classes = f.read().strip().split('\n')# 为不同的类别创建一个颜色列表
color_list = np.random.uniform(0, 255, size=(len(classes), 3))# 打开摄像头进行视频帧的捕获
cap = cv2.VideoCapture(0)# 初始化一个ThreadPoolExecutor用于多线程处理
executor = ThreadPoolExecutor(max_workers=2)# 定义fetch_frame函数,从视频流中获取视频帧
def fetch_frame(cap):ret, frame = cap.read()  # 读取一帧图像height, width, channels = frame.shape  # 获取图像的尺寸和通道信息return ret, frame, height, width, channels# 定义process_frame函数,处理每帧图像并进行目标检测
def process_frame(frame):# 将帧转换为模型的输入格式blob = cv2.dnn.blobFromImage(frame, 1 / 255.0, (416, 416), swapRB=True, crop=False)net.setInput(blob)output_layers = net.getUnconnectedOutLayersNames()  # 获取输出层的名字layer_outputs = net.forward(output_layers)  # 进行前向传播,获取检测结果boxes = []  # 用于存储检测到的边界框confidences = []  # 用于存储边界框的置信度class_ids = []  # 用于存储边界框的类别ID# 循环每个输出层的检测结果for output in layer_outputs:for detection in output:scores = detection[5:]  # 获取类别的得分class_id = np.argmax(scores)  # 获取得分最高的类别IDconfidence = scores[class_id]  # 获取得分最高的置信度# 过滤低置信度的检测结果if confidence > conf_threshold:center_x = int(detection[0] * width)center_y = int(detection[1] * height)w = int(detection[2] * width)h = int(detection[3] * height)# 计算边界框的位置和尺寸x = int(center_x - w / 2)y = int(center_y - h / 2)# 将边界框的位置、尺寸、置信度和类别ID添加到列表中boxes.append([x, y, w, h])confidences.append(float(confidence))class_ids.append(class_id)# 使用非极大值抑制去除重叠的边界框indices = cv2.dnn.NMSBoxes(boxes, confidences, conf_threshold, nms_threshold)# 在原图上绘制边界框和类别标签for i in indices.flatten():box = boxes[i]x = box[0]y = box[1]w = box[2]h = box[3]label = str(classes[class_ids[i]])color = color_list[class_ids[i]]cv2.rectangle(frame, (x, y), (x + w, y + h), color, 2)cv2.putText(frame, label, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)return frame# 在进入循环前,先读取一帧以开始异步处理
frame_future = executor.submit(fetch_frame, cap)# 主循环
while True:start = time.time()  # 记录开始处理的时间点# 获取当前帧和相应信息ret, frame, height, width, channels = frame_future.result()# 异步读取下一帧frame_future = executor.submit(fetch_frame, cap)# 如果当前帧读取成功,则继续处理if ret:# 使用线程池异步处理当前帧processed_frame = executor.submit(process_frame, frame).result()# 计算FPSend = time.time()fps = 1 / (end - start)# 在处理好的帧上显示FPScv2.putText(processed_frame, "FPS: " + str(round(fps, 2)), (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0),2)# 显示处理好的帧cv2.imshow('frame', processed_frame)# 如果我们按下 ‘q’ 键,退出循环if cv2.waitKey(1) & 0xFF == ord('q'):breakelse:break  # 如果帧没有被成功读取,退出循环# 释放视频捕获对象和销毁所有OpenCV窗口
cap.release()
cv2.destroyAllWindows()

效果展示

        这个效果还是不错的哈,就是这个硬件性能跟不上,要是有独显就好了。 


使用GPU说明

        当然了,为了在大学时期狠狠的奖励自己四年游戏,很多同学应该都是购买的游戏本,那么恭喜你,你的硬件非常的完美,那么这里你可以看一下。

如何操作

        如果你想利用 GPU 加速你的目标检测代码,主要更改会集中在如何让 OpenCV 利用你的 GPU。不幸的是,OpenCV 的 dnn 模块默认使用 CPU 进行计算。想要使用 GPU,首要条件是你需要有一个支持 CUDA 的 NVIDIA GPU。

        从 OpenCV 4.2 版本开始,dnn 模块添加了对 CUDA 的支持,但实现这一点需要确保你的 OpenCV 是用 CUDA 支持构建的。如果你自己编译 OpenCV,确保在编译时启用了 CUDA 支持。

以下是如何更改你的代码以利用 CUDA 的基本步骤:

1.在读取模型时启用 CUDA:

替换代码中的 readNet 调用,使用 readNetFromDarknet 并添加代码来设置网络的首选后端和目标为 CUDA。

   # 加载预训练的 YOLOv3 模型net = cv2.dnn.readNetFromDarknet('../needFiles/yolov3.cfg', '../needFiles/yolov3.weights')# 启用 CUDAnet.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA)
2.其它代码不需要做太多修改:

        使用CUDA优化后,主要是模型推理过程(即net.forward()的调用)会更快。数据准备和后处理(例如非极大值抑制)的代码不需要太多修改,因为它们仍然在 CPU 上执行。

        这些改动仅在你已有 OpenCV 版本支持 CUDA,并且你的系统拥有合适的 NVIDIA GPU 时有效。如果你的环境满足这些条件,这样的更改可以显著加快模型推理的速度,尤其是在进行视频流处理时。

        最后,你一定要确定你的环境(包括 NVIDIA 驱动程序和 CUDA Toolkit)被正确设置以支持 GPU 加速。如果你对如何编译支持 CUDA 的 OpenCV 或如何配置你的系统环境有任何疑问,我建议查阅 OpenCV 官方文档和 NVIDIA 的 CUDA 安装指导,因为我真的没有仔细研究过。

总结        

        希望这篇博客对你有所帮助。最后我想说,虽然NVIDIA对我们的学习有帮助,但是我还是想说。

AMDyes!!!

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

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

相关文章

【C语言】指针篇- 深度解析Sizeof和Strlen:热门面试题探究(5/5)

🌈个人主页:是店小二呀 🌈C语言笔记专栏:C语言笔记 🌈C笔记专栏: C笔记 🌈喜欢的诗句:无人扶我青云志 我自踏雪至山巅 文章目录 一、简单介绍Sizeof和Strlen1.1 Sizeof1.2 Strlen函数1.3 Sie…

快速建站介绍

随着在线业务和电子商务的规模不断扩大,初创公司、个人网站和小型企业都需要快速地搭建自己的网站,以便更好地展示自己、推广产品和服务,并实现在线交易。快速建站已成为在线业务发展的一种主流方式,因为它能够快速地创建一个响应…

uniapp 自定义 App启动图

由于uniapp默认的启动界面太过普通 所以需要自定义个启动图 普通的图片不可以过不了苹果的审核 所以使用storyboard启动图 生成 storyboard 的网站:初雪云-提供一站式App上传发布解决方案

Java学习第02天-类型转换、运算符

目录 类型转换 自动类型转换 表达式的自动类型转换 强制类型转换 运算符 基本运算符 案例解答 连接字符串 自增自减运算符 面试习题 赋值运算符 比较运算符 逻辑运算符 基本逻辑运算符 短路逻辑运算符 三元运算符 基础知识 拓展案例 运算符优先级 读取用户…

UNeXt: a Low-Dose CT denoising UNet model with the modified ConvNeXt block

UNeXt:采用改进的ConvNeXt块的低剂量CT去噪UNet模型 论文链接:https://ieeexplore.ieee.org/document/10095645 项目链接:没找到 Abstract 近几十年来,临床医生广泛使用计算机断层扫描(CT)进行医学诊断。医疗辐射有潜在危险&am…

77、贪心-买卖股票的最佳时机

思路 具体会导致全局最优,这里就可以使用贪心算法。方式如下: 遍历每一位元素找出当前元素最佳卖出是收益是多少。然后依次获取最大值,就是全局最大值。 这里可以做一个辅助数组:右侧最大数组,求右侧最大数组就要从…

ADS1.2中的代码debug的时候不出来代码的解决办法

我总觉得ADS1.2这个软件挺奇怪的,一阵一阵的,我遇到了很多奇怪的问题,这里记录一下吧。 1、新建文件的时候,没法选择这个add to project 解决办法:如果没有已存在的.mcp文件,就先新建project,然…

项目运行到手机端

运行到真机 手机和点到连在同一个wifi网络下面点击hbuiler上面的预览得到一个,network的网址这个时候去在手机访问,那么就可以访问网页了 跨域处理 这个时候可能会访问存在跨域问题 将uniapp的H5版本运行到真机进行调试,主要涉及到跨域问题…

java-Spring-mvc-(请求和响应)

目录 📌HTTP协议 超文本传输协议 请求 Request 响应 Response 🎨请求方法 GET请求 POST请求 📌HTTP协议 超文本传输协议 HTTP协议是浏览器与服务器通讯的应用层协议,规定了浏览器与服务器之间的交互规则以及交互数据的格式…

【机器学习】HQ-Edit引领图像编辑新潮流

科技新纪元:HQ-Edit引领图像编辑新潮流 一、HQ-Edit的诞生:一场技术的革命二、技术实现与优势:强大的编辑能力和精准的匹配三、应用前景与实例展示:InstructPix2Pix的突破 在数字化时代,图像编辑技术正以前所未有的速度…

M3D-NCA: Robust 3D Segmentation with Built-In Quality Control论文速读

文章目录 M3D-NCA: Robust 3D Segmentation with Built-In Quality Control摘要方法实验结果 M3D-NCA: Robust 3D Segmentation with Built-In Quality Control 摘要 这是关于医学图像分割的一篇论文的结构化总结: 背景和挑战: 医学图像分割依赖于大型…

【热闻速递】Google 裁撤 Python研发团队

🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 ​💫个人格言: "如无必要,勿增实体" 文章目录 【🔥热闻速递】Google 裁撤 Python研发团队引入研究结论 【&#x1f5…

xyctf ez_rand

[核心的代码就是这一部分,只要得到v4的值,也就是随机种子,那就可以把值弄出来了。所以我们需要做的就是爆破随机种子。 然后有一点是需要注意的,IDA这里显示的数据有可能是小端序的,所以我们需要export data&#xff…

DSP实时分析平台设计方案:924-6U CPCI振动数据DSP实时分析平台

6U CPCI振动数据DSP实时分析平台 一、产品概述 基于CPCI结构完成40路AD输入,30路DA输出的信号处理平台,处理平台采用双DSPFPGA的结构,DSP采用TI公司新一代DSP TMS320C6678,FPGA采用Xilinx V5 5VLX110T-1FF1136芯片&#xff…

向量的旋转矩阵

我们都知道,矩阵的乘法可以表示旋转。那么,这一理论的数学机理是什么呢?以及,这个旋转角度该怎么用矩阵表示呢? 本文用二维向量旋转来推导旋转矩阵的公式。假设,我们有一个向量P(x, y),准备通过…

手撕sql面试题:找出所有观看视频ID “1001“ 的观看时长大于他们观看视频ID “1002“ 的观看时长的用户ID

分享最近面试的sql面试题: 下面是表结构: CREATE TABLE video_records ( video_id char(4) NOT NULL COMMENT 视频id, user_id char(4) NOT NULL COMMENT 用户id, play_duration int NOT NULL COMMENT 观看时长, PRIMARY KEY (video_id,…

Ubuntu卸载已安装软件

前言 在Linux系统上安装了一些软件,但是卸载起来相比于Windows系统麻烦的多,这里总结了两种办法,希望对遇到这种问题的小伙伴能够有所帮助 1.Ubuntu Software 卸载 1.点击桌面上的Ubuntu Software并且选择installed 选中想要卸载的软件再按…

51. 【Android教程】JSON 数据解析

在上一节我们学习了 xml 数据格式,如果你觉得 xml 的数据比较冗余,标签、属性等等定义过于复杂,那么这一节我们将继续学习另一种更精简、更高效的数据格式—— Json。它广泛的运用于数据持久化以及网络传输中,这一节我们一起学习 …

Hi3519AV100 处理器⾼速全局快⻔相机

⾼速全局快⻔相机采⽤ 1英⼨全局快⻔ Sensor,⽀持 H.264/H.265 编码,8 百万 分辨率模式下最⾼帧率可达 50 帧/秒,1080P 模式下最⾼帧率可达 120 帧/秒。主控采⽤ Hi3519AV100 处理器,集成 2 Tops AI 算⼒ NPU ,⽀持⼤…

浮子式水位计施工细则

1浮子式水位计应安装在水位测井内,安装示意图见下图。 2设备安装要求 以测井中心为基准参考点,将水位计底板放在工作平台上。将悬索与平衡锤固定或锁紧,慢慢将平衡锤放至井底。 3)悬索另一端绕于水位轮,留长1m&#…