当前位置: 首页 > news >正文

YOLOv8 onnx 文件推理多线程加速视频流

运行环境:

  • MacOS:14.0
  • Python 3.9
  • Pytorch2.1
  • onnx 运行时

模型文件:

https://wwxd.lanzouu.com/iBqiA1g49pbc
密码:f40v

  • 下载 best.apk后将后缀名修改为 onnx 即可
  • 模型在英伟达 T4GPU 使用 coco128 训练了 200 轮
  • 如遇下载不了可私信获取

代码:

import copy
import timeimport onnxruntime as rt
import numpy as np
import cv2
import concurrent.futures# 前处理
def resize_image(image, size, letterbox_image):"""对输入图像进行resizeArgs:size:目标尺寸letterbox_image: bool 是否进行letterbox变换Returns:指定尺寸的图像"""ih, iw, _ = image.shapeh, w = size# letterbox_image = Falseif letterbox_image:scale = min(w / iw, h / ih)nw = int(iw * scale)nh = int(ih * scale)image = cv2.resize(image, (nw, nh), interpolation=cv2.INTER_LINEAR)image_back = np.ones((h, w, 3), dtype=np.uint8) * 128image_back[(h - nh) // 2: (h - nh) // 2 + nh, (w - nw) // 2:(w - nw) // 2 + nw, :] = imageelse:image_back = imagereturn image_backdef img2input(img):img = np.transpose(img, (2, 0, 1))img = img / 255return np.expand_dims(img, axis=0).astype(np.float32)def std_output(pred):"""将(1,84,8400)处理成(8400, 85)  85= box:4  conf:1 cls:80"""pred = np.squeeze(pred)pred = np.transpose(pred, (1, 0))pred_class = pred[..., 4:]pred_conf = np.max(pred_class, axis=-1)pred = np.insert(pred, 4, pred_conf, axis=-1)return preddef xywh2xyxy(*box):"""将xywh转换为左上角点和左下角点Args:box:Returns: x1y1x2y2"""ret = [box[0] - box[2] // 2, box[1] - box[3] // 2, \box[0] + box[2] // 2, box[1] + box[3] // 2]return retdef get_inter(box1, box2):"""计算相交部分面积Args:box1: 第一个框box2: 第二个狂Returns: 相交部分的面积"""x1, y1, x2, y2 = xywh2xyxy(*box1)x3, y3, x4, y4 = xywh2xyxy(*box2)# 验证是否存在交集if x1 >= x4 or x2 <= x3:return 0if y1 >= y4 or y2 <= y3:return 0# 将x1,x2,x3,x4排序,因为已经验证了两个框相交,所以x3-x2就是交集的宽x_list = sorted([x1, x2, x3, x4])x_inter = x_list[2] - x_list[1]# 将y1,y2,y3,y4排序,因为已经验证了两个框相交,所以y3-y2就是交集的宽y_list = sorted([y1, y2, y3, y4])y_inter = y_list[2] - y_list[1]# 计算交集的面积inter = x_inter * y_interreturn interdef get_iou(box1, box2):"""计算交并比: (A n B)/(A + B - A n B)Args:box1: 第一个框box2: 第二个框Returns:  # 返回交并比的值"""box1_area = box1[2] * box1[3]  # 计算第一个框的面积box2_area = box2[2] * box2[3]  # 计算第二个框的面积inter_area = get_inter(box1, box2)union = box1_area + box2_area - inter_area  # (A n B)/(A + B - A n B)iou = inter_area / unionreturn ioudef nms(pred, conf_thres, iou_thres):"""非极大值抑制nmsArgs:pred: 模型输出特征图conf_thres: 置信度阈值iou_thres: iou阈值Returns: 输出后的结果"""box = pred[pred[..., 4] > conf_thres]  # 置信度筛选cls_conf = box[..., 5:]cls = []for i in range(len(cls_conf)):cls.append(int(np.argmax(cls_conf[i])))total_cls = list(set(cls))  # 记录图像内共出现几种物体output_box = []# 每个预测类别分开考虑for i in range(len(total_cls)):clss = total_cls[i]cls_box = []temp = box[:, :6]for j in range(len(cls)):# 记录[x,y,w,h,conf(最大类别概率),class]值if cls[j] == clss:temp[j][5] = clsscls_box.append(temp[j][:6])#  cls_box 里面是[x,y,w,h,conf(最大类别概率),class]cls_box = np.array(cls_box)sort_cls_box = sorted(cls_box, key=lambda x: -x[4])  # 将cls_box按置信度从大到小排序# box_conf_sort = np.argsort(-box_conf)# 得到置信度最大的预测框max_conf_box = sort_cls_box[0]output_box.append(max_conf_box)sort_cls_box = np.delete(sort_cls_box, 0, 0)# 对除max_conf_box外其他的框进行非极大值抑制while len(sort_cls_box) > 0:# 得到当前最大的框max_conf_box = output_box[-1]del_index = []for j in range(len(sort_cls_box)):current_box = sort_cls_box[j]iou = get_iou(max_conf_box, current_box)if iou > iou_thres:# 筛选出与当前最大框Iou大于阈值的框的索引del_index.append(j)# 删除这些索引sort_cls_box = np.delete(sort_cls_box, del_index, 0)if len(sort_cls_box) > 0:# 我认为这里需要将clas_box先按置信度排序, 才能每次取第一个output_box.append(sort_cls_box[0])sort_cls_box = np.delete(sort_cls_box, 0, 0)return output_boxdef cod_trf(result, pre, after):"""因为预测框是在经过letterbox后的图像上做预测所以需要将预测框的坐标映射回原图像上Args:result:  [x,y,w,h,conf(最大类别概率),class]pre:    原尺寸图像after:  经过letterbox处理后的图像Returns: 坐标变换后的结果,"""res = np.array(result)x, y, w, h, conf, cls = res.transpose((1, 0))x1, y1, x2, y2 = xywh2xyxy(x, y, w, h)  # 左上角点和右下角的点h_pre, w_pre, _ = pre.shapeh_after, w_after, _ = after.shapescale = max(w_pre / w_after, h_pre / h_after)  # 缩放比例h_pre, w_pre = h_pre / scale, w_pre / scale  # 计算原图在等比例缩放后的尺寸x_move, y_move = abs(w_pre - w_after) // 2, abs(h_pre - h_after) // 2  # 计算平移的量ret_x1, ret_x2 = (x1 - x_move) * scale, (x2 - x_move) * scaleret_y1, ret_y2 = (y1 - y_move) * scale, (y2 - y_move) * scaleret = np.array([ret_x1, ret_y1, ret_x2, ret_y2, conf, cls]).transpose((1, 0))return retdef draw(res, image, cls):"""将预测框绘制在image上Args:res: 预测框数据image: 原图cls: 类别列表,类似["apple", "banana", "people"]  可以自己设计或者通过数据集的yaml文件获取Returns:"""for r in res:# 画框image = cv2.rectangle(image, (int(r[0]), int(r[1])), (int(r[2]), int(r[3])), (255, 0, 0), 1)# 表明类别text = "{}:{}".format(cls[int(r[5])], round(float(r[4]), 2))h, w = int(r[3]) - int(r[1]), int(r[2]) - int(r[0])  # 计算预测框的长宽font_size = min(h / 640, w / 640) * 3  # 计算字体大小(随框大小调整)image = cv2.putText(image, text, (max(10, int(r[0])), max(20, int(r[1]))), cv2.FONT_HERSHEY_COMPLEX,max(font_size, 0.3), (0, 0, 255), 1)  # max()为了确保字体不过界return imagedef display_fps(frame, start_time):global global_fpsend_time = time.time()elapsed_time = end_time - start_timeglobal_fps = 1 / elapsed_time# 在图像上显示帧率cv2.putText(frame, f"FPS: {global_fps:.2f}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2, cv2.LINE_AA)global_fps = 0.0if __name__ == '__main__':cap = cv2.VideoCapture(0)sess = rt.InferenceSession('./best.onnx')cv2.namedWindow('Video Stream', cv2.WINDOW_NORMAL)names = ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light','fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow','elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee','skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard','tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple','sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch','potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard','cell phone', 'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors','teddy bear', 'hair drier', 'toothbrush']def inference_task(frame):class_list = list(names)std_h, std_w = 640, 640img_after = resize_image(frame, (std_w, std_h), True)data = img2input(img_after)input_name = sess.get_inputs()[0].namelabel_name = sess.get_outputs()[0].namepred = sess.run([label_name], {input_name: data})[0]pred = std_output(pred)result = nms(pred, 0.6, 0.4)result = cod_trf(result, frame, img_after)image = draw(result, frame, class_list)return imagewith concurrent.futures.ThreadPoolExecutor(max_workers=20) as executor:while True:start_time = time.time()# 读取一帧ret, frame = cap.read()if not ret:print("无法读取帧")break# 提交任务并获取 Future 对象future = executor.submit(inference_task, frame)display_fps(frame, start_time)# 获取结果try:image = future.result()# 显示窗口cv2.imshow('Video Stream', image)cv2.waitKey(1)except Exception as e:cv2.imshow('Video Stream', frame)cv2.waitKey(1)# 释放资源cap.release()cv2.destroyAllWindows()

相关文章:

YOLOv8 onnx 文件推理多线程加速视频流

运行环境&#xff1a; MacOS&#xff1a;14.0Python 3.9Pytorch2.1onnx 运行时 模型文件&#xff1a; https://wwxd.lanzouu.com/iBqiA1g49pbc 密码:f40v 下载 best.apk后将后缀名修改为 onnx 即可模型在英伟达 T4GPU 使用 coco128 训练了 200 轮如遇下载不了可私信获取 代码…...

CVE-2017-12615 文件上传

CVE-2017-12615 文件上传 当存在漏洞的Tomcat运行在Windows/Linux主机上&#xff0c; 且启用了HTTP PUT请求方法&#xff08; 例如&#xff0c; 将readonly初始化参数由默认值设置为false&#xff09; &#xff0c; 攻击者将有可能可通过精心构造的攻击请求数据包向服务器上传…...

c++没有返回值的返回值

上面的函数search没有返回值,因为a不等于1,但是输出的时候会输出6.这恰巧是x的值,如果我们希望a不等于1时返回x,那么这种结果反而是正确的.有时候这种错误的代码可能产生正确的结果反而会加大debug难度 int search(int n) { 00007FF66DB723E0 mov dword ptr [rsp8],e…...

全网最全卡方检验汇总

一文整理了卡方检验全部内容&#xff0c;包括卡方检验的定义&#xff08;基本思想、卡方值计算、适用条件分析&#xff09;、卡方检验分类&#xff08;2*2四格表卡方、R*C表格卡方、配对卡方、卡方拟合优度检验、分层卡方&#xff09;、卡方检验如何分析&#xff08;数据格式、…...

Java基础-中级-高级面试题汇(一)

第一部分&#xff1a; Java基础面试题汇总 1.面向对象和面向过程的区别&#xff1f; 面向对象和面向过程是两种不同的编程思想。面向对象是一种以对象为中心的编程思想&#xff0c;将数据和处理数据的方法封装在一起&#xff0c;形成一个类。程序通过创建对象来调用类中的方法…...

数据结构 / day04 作业

1. 单链表任意位置删除, 单链表任意位置修改, 单链表任意位置查找, 单链表任意元素查找, 单链表任意元素修改, 单链表任意元素删除, 单链表逆置 // main.c#include "head.h"int main(int argc, const char *argv[]) {Linklist headNULL; //head 是头指针// printf(&q…...

Java核心知识点整理大全20-笔记

目录 17. 设计模式 17.1.1. 设计原则 17.1.24. 解释器模式 18. 负载均衡 18.1.1.1. 四层负载均衡&#xff08;目标地址和端口交换&#xff09; 18.1.1.2. 七层负载均衡&#xff08;内容交换&#xff09; 18.1.2. 负载均衡算法/策略 18.1.2.1. 轮循均衡&#xff08;Roun…...

Spark---转换算子、行动算子、持久化算子

一、转换算子和行动算子 1、Transformations转换算子 1&#xff09;、概念 Transformations类算子是一类算子&#xff08;函数&#xff09;叫做转换算子&#xff0c;如map、flatMap、reduceByKey等。Transformations算子是延迟执行&#xff0c;也叫懒加载执行。 2)、Transf…...

什么是关系型数据库?

什么是关系型数据库&#xff1f; 关系型数据库&#xff08;RDBMS&#xff09;是建立在关系模型基础上的数据库系统。关系模型是一种数据模型&#xff0c;它表示数据之间的联系&#xff0c;包括一对一、一对多和多对多的关系。在关系型数据库中&#xff0c;数据以表格的形式存储…...

【LeetCode】挑战100天 Day12(热题+面试经典150题)

【LeetCode】挑战100天 Day12&#xff08;热题面试经典150题&#xff09; 一、LeetCode介绍二、LeetCode 热题 HOT 100-142.1 题目2.2 题解 三、面试经典 150 题-143.1 题目3.2 题解 一、LeetCode介绍 LeetCode是一个在线编程网站&#xff0c;提供各种算法和数据结构的题目&…...

ArcGIS10.x系列 Python工具箱教程

ArcGIS10.x系列 Python工具箱教程 目录 1.前提 2.需要了解的资料 3.Python工具箱制作教程 4. Python工具箱具体样例代码&#xff08;DEM流域分析-河网等级矢量化&#xff09; 1.前提 如果你想自己写Python工具箱&#xff0c;那么假定你已经会ArcPy&#xff0c;如果只是自己…...

【蓝桥杯】刷题

刷题网站 记录总结刷题过程中遇到的一些问题 1、最大公约数与最小公倍数 a,bmap(int,input().split())sa*bwhile a%b:a,bb,a%bprint(b,s//b)2.迭代法求平方根(题号1021) #include<stdio.h> #include<math.h> int main() {double x11.0,x2;int a;scanf("%d&…...

软件产品登记的材料条件

(1&#xff09;申请双软认证前应该要获得信息产业部授权的软件检测机构出具的检测证明&#xff0c;这份检测证明可以到软件行业协会申请&#xff0c;然后协会会派专家到公司进行“检测”&#xff0c;检测通过后出具证明&#xff0c;这份证明的申请与软件著作权等无关&#xff0…...

春节后跟进客户开发信模板?外贸邮件模板?

适合新年的客户开发信模板&#xff1f;年后给客户的邮件怎么写&#xff1f; 在春节这一传统的中国节日结束后&#xff0c;跟进客户对于维持和发展业务至关重要。客户开发信模板是一种有效的工具。蜂邮将介绍一些春节后跟进客户开发信模板的关键技巧&#xff0c;以确保您的业务…...

个人财务管理软件CheckBook Pro mac中文版特点介绍

CheckBook Pro mac是一款Mac平台的个人财务管理软件&#xff0c;主要用于跟踪个人收入、支出和账户余额等信息。 CheckBook Pro mac 软件特点 简单易用&#xff1a;该软件的用户界面非常简洁明了&#xff0c;即使您是初学者也可以轻松上手。 多账户管理&#xff1a;该软件支持…...

rfc4301- IP 安全架构

1. 引言 1.1. 文档内容摘要 本文档规定了符合IPsec标准的系统的基本架构。它描述了如何为IP层的流量提供一组安全服务&#xff0c;同时适用于IPv4 [Pos81a] 和 IPv6 [DH98] 环境。本文档描述了实现IPsec的系统的要求&#xff0c;这些系统的基本元素以及如何将这些元素结合起来…...

【数据结构/C++】线性表_双链表基本操作

#include <iostream> using namespace std; typedef int ElemType; // 3. 双链表 typedef struct DNode {ElemType data;struct DNode *prior, *next; } DNode, *DLinkList; // 初始化带头结点 bool InitDNodeList(DLinkList &L) {L (DNode *)malloc(sizeof(DNode))…...

前端已死?看看我的秋招上岸历程

背景 求职方向&#xff1a;web前端 技术栈&#xff1a;vue2、springboot&#xff08;学校开过课&#xff0c;简单的学习过&#xff09; 实习经历&#xff1a;两段&#xff0c;但都是实训类的&#xff0c;说白了就是类似培训&#xff0c;每次面试官问起时我也会坦诚交代&…...

Flink Flink中的合流

一、Flink中的基本合流操作 在实际应用中&#xff0c;我们经常会遇到来源不同的多条流&#xff0c;需要将它们的数据进行联合处理。所以 Flink 中合流的操作会更加普遍&#xff0c;对应的 API 也更加丰富。 二、联合&#xff08;Union&#xff09; 最简单的合流操作&#xf…...

工业园区重金属废水深度处理工程项目,稳定出水0.1mg/l

随着环保要求不断提高&#xff0c;工业废水处理已成为众多企业的必修课。然而在工业生产中&#xff0c;如何有效处理含有重金属的废水成为了一个关键的挑战。 重金属废水是指含有汞、铅、铜、镉、锌、镍等有毒有害物质的废水&#xff0c;来源于矿山开采、金属冶炼、电镀、印刷线…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表&#xff1f;1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

HTML 列表、表格、表单

1 列表标签 作用&#xff1a;布局内容排列整齐的区域 列表分类&#xff1a;无序列表、有序列表、定义列表。 例如&#xff1a; 1.1 无序列表 标签&#xff1a;ul 嵌套 li&#xff0c;ul是无序列表&#xff0c;li是列表条目。 注意事项&#xff1a; ul 标签里面只能包裹 li…...

如何在看板中有效管理突发紧急任务

在看板中有效管理突发紧急任务需要&#xff1a;设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP&#xff08;Work-in-Progress&#xff09;弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中&#xff0c;设立专门的紧急任务通道尤为重要&#xff0c;这能…...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

使用LangGraph和LangSmith构建多智能体人工智能系统

现在&#xff0c;通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战&#xff0c;比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...

免费数学几何作图web平台

光锐软件免费数学工具&#xff0c;maths,数学制图&#xff0c;数学作图&#xff0c;几何作图&#xff0c;几何&#xff0c;AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...

Linux nano命令的基本使用

参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时&#xff0c;显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...

给网站添加live2d看板娘

给网站添加live2d看板娘 参考文献&#xff1a; stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下&#xff0c;文章也主…...