OpenCV 与 YoloV3的结合使用:目标实时跟踪

目录
代码分析
1. YOLO 模型加载
2. 视频加载与初始化
3. 视频帧处理
4. 物体检测
5. 处理检测结果
6. 边界框和类别显示
7. 帧率(FPS)计算
8. 结果显示与退出
9. 资源释放
整体代码
效果展示
总结
代码分析
这段代码使用 YOLO(You Only Look Once)模型进行视频中的物体检测,并通过 OpenCV 显示检测结果。以下是代码的详细分析:
1. YOLO 模型加载
net = cv2.dnn.readNet('../../needFiles/yolov3.weights', '../../needFiles/yolov3.cfg')
- 这行代码加载了预先训练的 YOLOv3 模型的权重文件(
yolov3.weights)和配置文件(yolov3.cfg)。YOLOv3 是一个实时物体检测模型,能够检测多个类别的物体。
layer_names = net.getLayerNames()
output_layers = [layer_names[i - 1] for i in net.getUnconnectedOutLayers()]
getLayerNames()获取网络的所有层名称。getUnconnectedOutLayers()返回网络输出层的索引(通常是 YOLO 的 3 个输出层),通过索引列表,获取这些输出层的名称,用于后面的forward方法中。
2. 视频加载与初始化
video_path = 'D:/Dji/DJIneo.mp4'
cap = cv2.VideoCapture(video_path)
- 使用
cv2.VideoCapture来加载视频文件。如果视频路径正确,cap将用于逐帧读取视频。
resize_scale = 0.3
- 定义缩放比例为 0.3,用于后续缩小显示尺寸,以减少计算量。
prev_time = 0
- 初始化变量
prev_time,用于计算帧率(FPS,Frames Per Second)。
3. 视频帧处理
while True:ret, frame = cap.read()if not ret:break
- 逐帧读取视频内容,
cap.read()返回两个值,ret是布尔值表示是否成功读取,frame是当前帧图像。如果无法读取(如视频结束),则退出循环。
frame_resized = cv2.resize(frame, (0, 0), fx=resize_scale, fy=resize_scale)
- 当前帧
frame被缩小到原来的 30%(通过resize_scale),用于加快后续处理。
4. 物体检测
blob = cv2.dnn.blobFromImage(frame_resized, 0.00392, (416, 416), (0, 0, 0), True, crop=False)
net.setInput(blob)
outs = net.forward(output_layers)
- YOLO 模型需要特定格式的输入。
blobFromImage将图像转换为 YOLO 需要的 4D blob,归一化比例为0.00392,图像大小调整为(416, 416)。net.setInput(blob)将处理后的 blob 输入到网络,net.forward(output_layers)得到检测结果。
5. 处理检测结果
class_ids = []
confidences = []
boxes = []
- 初始化三个列表:
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:...
- 遍历 YOLO 输出的
outs,每个detection包含检测到的一个物体的信息。检测结果中的前 4 个值是物体的位置信息,后面的值是类别的置信度。np.argmax(scores)找出置信度最高的类别,confidence存储该类别的置信度。如果置信度超过 0.5,则认为该物体被成功检测。
6. 边界框和类别显示
indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)
for i in indexes.flatten():x, y, w, h = boxes[i]label = str(class_ids[i])cv2.rectangle(frame_resized, (x, y), (x + w, y + h), (0, 255, 0), 2)cv2.putText(frame_resized, label, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)
- 使用非极大值抑制(NMS,Non-Maximum Suppression)去除重叠的边界框,减少冗余检测结果。然后,遍历保留下来的边界框,在图像上绘制矩形框和类别标签。
7. 帧率(FPS)计算
current_time = time.time()
fps = 1 / (current_time - prev_time)
prev_time = current_time
cv2.putText(frame_resized, f'FPS: {int(fps)}', (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)
- 通过计算两帧之间的时间差,实时计算并显示 FPS,以评估模型的运行效率。
8. 结果显示与退出
cv2.imshow('Object Detection', frame_resized)
if cv2.waitKey(1) & 0xFF == ord('q'):break
- 使用
imshow显示检测结果,按 'q' 键退出循环。
9. 资源释放
cap.release()
cv2.destroyAllWindows()
- 释放视频资源并关闭所有窗口。
整体代码
import cv2
import numpy as np
import time# 加载 YOLO 模型
net = cv2.dnn.readNet('../../needFiles/yolov3.weights', '../../needFiles/yolov3.cfg')
layer_names = net.getLayerNames()
output_layers = [layer_names[i - 1] for i in net.getUnconnectedOutLayers()] # 修正索引问题# 加载视频
video_path = 'D:/Dji/DJIneo.mp4'
cap = cv2.VideoCapture(video_path)# 缩小显示尺寸
resize_scale = 0.3# 初始化时间和帧计数器
prev_time = 0# 处理视频的每一帧
while True:ret, frame = cap.read()if not ret:break# 缩小当前帧frame_resized = cv2.resize(frame, (0, 0), fx=resize_scale, fy=resize_scale)# 检测对象blob = cv2.dnn.blobFromImage(frame_resized, 0.00392, (416, 416), (0, 0, 0), True, crop=False)net.setInput(blob)outs = net.forward(output_layers)# 处理检测结果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: # 置信度阈值center_x = int(detection[0] * frame_resized.shape[1])center_y = int(detection[1] * frame_resized.shape[0])w = int(detection[2] * frame_resized.shape[1])h = int(detection[3] * frame_resized.shape[0])x = int(center_x - w / 2)y = int(center_y - h / 2)boxes.append([x, y, w, h])confidences.append(float(confidence))class_ids.append(class_id)# 应用非极大抑制来去除冗余框indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)for i in indexes.flatten(): # 展平索引x, y, w, h = boxes[i]label = str(class_ids[i])cv2.rectangle(frame_resized, (x, y), (x + w, y + h), (0, 255, 0), 2)cv2.putText(frame_resized, label, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)# 计算 FPScurrent_time = time.time()fps = 1 / (current_time - prev_time)prev_time = current_time# 显示 FPScv2.putText(frame_resized, f'FPS: {int(fps)}', (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)# 显示结果cv2.imshow('Object Detection', frame_resized)# 按 'q' 键退出if cv2.waitKey(1) & 0xFF == ord('q'):break# 释放资源
cap.release()
cv2.destroyAllWindows()
效果展示
YOLOV3实现目标识别
总结
这,呃,不总结了
相关文章:
OpenCV 与 YoloV3的结合使用:目标实时跟踪
目录 代码分析 1. YOLO 模型加载 2. 视频加载与初始化 3. 视频帧处理 4. 物体检测 5. 处理检测结果 6. 边界框和类别显示 7. 帧率(FPS)计算 8. 结果显示与退出 9. 资源释放 整体代码 效果展示 总结 代码分析 这段代码使用 YOLO(…...
Worse is Better
Worse is Better是UNIX的设计哲学,通俗来说,就是:保持接口与实现的简单性,比系统的任何其他属性,包括准确性、一致性和完整性,都来得更加重要 设计系统时,接口和实现的简单性是至关重要的。这种…...
Python Web 框架篇:Flask、Django、FastAPI介绍及其核心技术
Python Web 框架篇:Flask、Django、FastAPI介绍及其核心技术 目录 🐍 Flask Flask 核心概念(路由、视图函数、模板渲染)Flask Blueprint 模块化应用Flask 扩展(Flask-SQLAlchemy、Flask-WTF、Flask-Migrate 等&#…...
【Qt网络编程基础】Tcp服务器和客户端(只支持一对一)
目录 一、编写思路 1、服务器 总体思路 详细思路 1. 构造函数 (Widget::Widget) 2. 启动监听 (Widget::on_btn_start_clicked) 3. 停止监听 (Widget::on_btn_cease_clicked) 4. 发送消息 (Widget::on_btn_info_clicked) 5. 接收消息 (Widget::receive_message) 6. 处…...
平台开发到落地详解:从食堂采购系统源码到可视化供应链管理数据大屏
随着数字化转型的加速,越来越多的企业和组织开始重视供应链的智能化与可视化管理。在食堂采购领域,供应链管理的复杂性与日俱增,而传统的手工操作往往效率低下、容易出错。因此,开发食堂采购系统并结合可视化数据大屏的解决方案&a…...
静态内部类
目录 一、什么是静态内部类二、静态内部类的意义 一、什么是静态内部类 在 Java 中,静态内部类(也称为静态嵌套类)是定义在一个类内部的类,但它与外部类没有关联,即它不持有外部类的引用。静态内部类可以访问外部类的…...
Vue+SpringBoot+数据库整体开发流程 1
本篇文章通过springboot整合mybatis-plus去实现后端对数据库的增删改查,以及响应给前端的url,让前端获得数据。 目录 一、简单搭建一个Vue项目 检查node.js版本 使用vue-cli创建空项目 Vue-cli工程中每个文件夹和文件的用处 二、Mysql数据库 创建数…...
百度Apollo打通与ROS的通信,扩展自动驾驶系统生态
技术文档|打通与ROS的通信,扩展自动驾驶系统生态_Apollo开发者社区 (baidu.com)...
Web3 项目安全手册
现如今针对 Web3 项目的攻击手法层出不穷,且项目之间的交互也越发复杂,在各个项目之间的交互经常会引入新的安全问题,而大部分 Web3 项目研发团队普遍缺少的一线的安全攻防经验,并且在进行 Web3 项目研发的时候,重点关…...
AI边缘计算在安防领域的智能化革新:赋能安防系统的智能化升级
随着人工智能(AI)和边缘计算技术的快速发展,两者在安防视频领域的应用日益广泛,为传统安防系统带来了革命性的变革。AI边缘计算技术通过将AI算法和模型部署在边缘设备上,实现了数据处理和智能决策的即时响应࿰…...
vscode配置C/C++环境(保姆级详细教程)
一. 引言 VSCode,全称为Visual Studio Code,是一款由微软开发的免费、开源的轻量级代码编辑器,它支持多种编程语言和平台,并提供丰富的扩展功能,让开发者能够更高效地编写代码。 大家能来搜用如何在VSCode配置C/C环境…...
MDK keil STM32 局部变量不能查看值,显示为not in scope
用MDK调试程序,查看变量时watch窗口总是和 一、方法1:优化级别改为Level 0 1 编译器把这个局部变量给优化掉了,并没有在内存中生成,把优化级别改为Level 0,重新编译。 Keil默认优化是等级3,最高优化&…...
表连接查询之两个left join与递归SQL
一、如下SQL1 SELECT i.*,su1.name as createName,su2.name as updateNameFROM information ileft join sys_user su1 on su1.idi.create_idleft join sys_user su2 on su2.idi.update_id 二、分析 1、SELECT i.*,su.name as createName,sua.name as updateName FROM informati…...
2024.9.10
打的模拟赛难度很大,T1就2200分? 其中转化成差分数组上的问题很巧妙 还用了将数分成2的多次方的形式,这种套路在最近的几场比赛和题中都见到过,值得归纳一下 T3是长链剖分和对顶堆维护,太难写了还没写出来 T4仍然是概率题,但是并没有见过类似的出题方式,其中关键是:最大独…...
22_图论中的高级数据结构
菜鸟:老鸟,我最近在处理一个网络节点数据的问题,发现代码运行得特别慢。你能帮我看看有什么优化的方法吗? 老鸟:当然可以。你处理的是图结构对吗?你是如何存储和操作这些节点的? 菜鸟…...
axure判断
在auxre中我们也可以实现判断的功能,当目标等于什么内容时则执行下方的功能。 一、判断输入框中是否有值 画布添加一个输入框、一个文本标签删除其中内容,添加一个按钮,输入框命名为【文本显示】文本标签命名为【提示】 给按钮新增一个交互…...
【开源大模型生态7】华为的盘古大模型
鹏程盘古模型是全球首个全开源2000亿参数的自回归中文预训练语言大模型,在知识问答、知识检索、知识推理、阅读理解等文本生成领域表现突出。 2070亿参数,64层。 这里注意几个概念。 参数(Parameters): 参数是指构成模…...
SprinBoot+Vue远程教育网站的设计与实现
目录 1 项目介绍2 项目截图3 核心代码3.1 Controller3.2 Service3.3 Dao3.4 application.yml3.5 SpringbootApplication3.5 Vue 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍:CSDN认证博客专家,CSDN平台Java领域优质…...
docker的基本操作
目录 一,应用部署 创建容器 进入容器 创建有端口的容器 通过ssh进入容器 二、镜像操作 搜索镜像 拉取镜像 查看本地镜像 删除镜像 导入镜像 三、容器操作 创建并启动容器 使用 docker run 命令创建并启动一个容器 创建一个有端口号的容器 查看正在运…...
理解 RabbitMQ:生产者、连接、通道、交换机、队列与消费者的消息流
在分布式消息系统中,RabbitMQ 是一个非常流行的消息代理。它的核心理念是解耦应用程序的生产者和消费者,使得消息能够可靠地从一方传递到另一方。本文将带你深入了解 RabbitMQ 中 生产者、连接、通道、交换机、队列 和 消费者 之间的消息流,并…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...
Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...
初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...
动态 Web 开发技术入门篇
一、HTTP 协议核心 1.1 HTTP 基础 协议全称 :HyperText Transfer Protocol(超文本传输协议) 默认端口 :HTTP 使用 80 端口,HTTPS 使用 443 端口。 请求方法 : GET :用于获取资源,…...
