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

使用onnxruntime-web 运行yolov8-nano推理

ONNX(Open Neural Network Exchange)模型具有以下两个特点促成了我们可以使用onnxruntime-web 直接在web端上运行推理模型,为了让这个推理更直观,我选择了试验下yolov8 识别预览图片:

1. 跨平台兼容性

ONNX 是一种开放的格式,可以在不同的深度学习框架之间共享模型,如 PyTorch、TensorFlow、MXNet 和 Caffe2。这使得用户可以在一个框架中训练模型,然后在另一个框架中进行推理。

2. 模型标准化

ONNX 提供了一种标准化的模型表示,定义了操作符、数据类型和模型结构。这种标准化使得不同工具和库可以一致地理解和处理模型。

3. 高效性

ONNX 模型在推理时通常能够实现更高的效率,特别是在使用 ONNX Runtime 时。ONNX Runtime 是一个高性能的推理引擎,支持多种硬件加速(如 GPU、TPU 等)。

YOLOv8n 是 YOLOv8 系列中的 "nano" 版本,通常是指模型较小,参数较少,计算需求低。适合在资源受限的环境中使用,如移动设备和嵌入式系统。

首先需要下载这两个模型

yolov8n.onnx

nms-yolov8.onnx

https://huggingface.co/SpotLab/YOLOv8Detection/blob/3005c6751fb19cdeb6b10c066185908faf66a097/yolov8n.onnx

关于这两个模型可以多说两句,YOLOv8 和非极大值抑制(NMS)是目标检测任务中的两个关键组成部分。它们一起工作,以实现高效且精确的目标检测。以下是它们如何协同工作的详细说明:

1. YOLOv8 的工作原理

  • 目标检测:YOLOv8 模型接收输入图像,并通过其深度神经网络对图像进行处理,生成多个候选边界框和相应的置信度分数。这些边界框用于定位检测到的对象。
  • 多类别检测:模型还能为每个边界框预测对象的类别,通常是通过 softmax 函数生成类别概率。

2. NMS 的作用

  • 去除冗余检测:由于模型可能会为同一对象生成多个重叠的边界框,NMS 被用来过滤这些冗余的框。NMS 通过以下步骤工作:
    • 排序:根据置信度分数对所有预测框进行排序,选择置信度最高的框作为参考框。
    • 计算重叠:计算参考框与其他框之间的交并比(IoU)。
    • 阈值过滤:如果其他框与参考框的 IoU 超过设定的阈值,则认为这些框是冗余的,并将其移除。
    • 重复处理:对剩余框重复上述过程,直到所有框都被处理完。

3. 工作流程

  1. 输入图像:将图像输入到 YOLOv8 模型。
  2. 生成候选框:模型输出多个候选边界框和相应的置信度分数。
  3. 应用 NMS
    • 将所有候选框传递给 NMS。
    • NMS 处理并返回最终的边界框和类别标签,去除了冗余框,确保每个对象只保留一个最优框

使用python 代码进行检测的时候是这样用的

# 假设 model 是 YOLOv8 模型,image 是输入图像
boxes, scores, class_ids = model.predict(image)# 应用 NMS
final_boxes, final_scores, final_class_ids = nms(boxes, scores, threshold)# 结果可视化
for box, score, class_id in zip(final_boxes, final_scores, final_class_ids):draw_box(image, box, score, class_id)

在web项目里使用onnxruntime-web 要简单些

import React, { useState, useRef } from "react";
import cv from "@techstark/opencv-js";
import { Tensor, InferenceSession } from "onnxruntime-web";
import Loader from "./components/loader";
import { detectImage } from "./utils/detect";
import { download } from "./utils/download";
import "./style/App.css";const App = () => {const [session, setSession] = useState(null);const [loading, setLoading] = useState({ text: "Loading OpenCV.js", progress: null });const [image, setImage] = useState(null);const inputImage = useRef(null);const imageRef = useRef(null);const canvasRef = useRef(null);// Configsconst modelName = "yolov8n.onnx";const modelInputShape = [1, 3, 640, 640];const topk = 100;const iouThreshold = 0.45;const scoreThreshold = 0.25;// wait until opencv.js initializedcv["onRuntimeInitialized"] = async () => {const baseModelURL = `${process.env.PUBLIC_URL}/model`;// create sessionconst url =`${baseModelURL}/${modelName}`console.log(`url:${url}`)const arrBufNet = await download(url, // url["加载 YOLOv8", setLoading] // logger);const yolov8 = await InferenceSession.create(arrBufNet);const arrBufNMS = await download(`${baseModelURL}/nms-yolov8.onnx`, // url["加载 NMS model", setLoading] // logger);const nms = await InferenceSession.create(arrBufNMS);// warmup main modelsetLoading({ text: "model 预热...", progress: null });const tensor = new Tensor("float32",new Float32Array(modelInputShape.reduce((a, b) => a * b)),modelInputShape);await yolov8.run({ images: tensor });setSession({ net: yolov8, nms: nms });setLoading(null);};return (<div className="App">{loading && (<Loader>{loading.progress ? `${loading.text} - ${loading.progress}%` : loading.text}</Loader>)}<div className="header"><h1>onnxruntime-web 测试</h1></div><div className="content"><imgref={imageRef}src="#"alt=""style={{ display: image ? "block" : "none" }}onLoad={() => {detectImage(imageRef.current,canvasRef.current,session,topk,iouThreshold,scoreThreshold,modelInputShape);}}/><canvasid="canvas"width={modelInputShape[2]}height={modelInputShape[3]}ref={canvasRef}/></div><inputtype="file"ref={inputImage}accept="image/*"style={{ display: "none" }}onChange={(e) => {// handle next image to detectif (image) {URL.revokeObjectURL(image);setImage(null);}const url = URL.createObjectURL(e.target.files[0]); // create image urlimageRef.current.src = url; // set image sourcesetImage(url);}}/><div className="btn-container"><buttononClick={() => {inputImage.current.click();}}>打开图片</button>{image && (/* show close btn when there is image */<buttononClick={() => {inputImage.current.value = "";imageRef.current.src = "#";URL.revokeObjectURL(image);setImage(null);}}>关闭图片</button>)}</div></div>);
};export default App;
  • session 用于存储模型的推理会话。
  • loading 用于管理加载状态和进度。
  • image 存储用户选择的图像。
  • inputImageimageRefcanvasRef 是对 DOM 元素的引用。

上面加载的顺序是 在 OpenCV.js 加载完成后,异步加载 YOLOv8 和 NMS 模型。使用 download 函数从指定 URL 下载模型,并创建推理会话。模型有个预热的过程

创建一个形状为 const modelInputShape = [1, 3, 640, 640]  的空张量,并运行一次模型以进行预热,确保模型准备就绪。

页面使用 <canvas> 元素来绘制检测结果。

运行测试下效果

web使用onnx这个事给我很多启发,之前训练的一些模型完全可以在前端就实现推理

相关文章:

使用onnxruntime-web 运行yolov8-nano推理

ONNX&#xff08;Open Neural Network Exchange&#xff09;模型具有以下两个特点促成了我们可以使用onnxruntime-web 直接在web端上运行推理模型&#xff0c;为了让这个推理更直观&#xff0c;我选择了试验下yolov8 识别预览图片&#xff1a; 1. 跨平台兼容性 ONNX 是一种开…...

Gin框架html/vue前端使用hls.js播放/点播m3u8(hls)格式视频

说明 在web应用开发时遇到在线播放m3u8格式视频&#xff0c;由于m3u8是多分片视频&#xff0c;原生video标签无法直接播放&#xff0c;所以需要js对m3u8处理才能播放&#xff0c;网上有很多插件&#xff0c;这里我选择最近简单方法hls.js播放&#xff0c;引入一个js文件即可。…...

HarmonyOS 私仓搭建

1. HarmonyOS 私仓搭建 私仓搭建文档&#xff1a;https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/ide-ohpm-repo-quickstart-V5   发布共享包[https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/ide-har-publish-0000001597973129-V5]…...

Mybatis学习笔记(二)

八、多表联合查询 (一) 多表联合查询概述 在开发过程中单表查询不能满足项目需求分析功能&#xff0c;对于复杂业务来讲&#xff0c;关联的表有几张&#xff0c;甚至几十张并且表与表之间的关系相当复杂。为了能够实业复杂功能业务&#xff0c;就必须进行多表查询&#xff0c…...

Google“Big Sleep“人工智能项目发现真实软件漏洞

据Google研究人员称&#xff0c;该公司的一个人工智能项目足够聪明&#xff0c;能够自行发现现实世界中的软件漏洞&#xff1b;Google的人工智能项目最近在开源数据库引擎 SQLite 中发现了一个之前未知的可利用漏洞。 该公司随后在正式软件发布之前报告了这一漏洞&#xff0c;这…...

npm入门教程5:package.json

一、package.json 文件的作用 依赖管理&#xff1a;列出项目所依赖的包&#xff08;库&#xff09;及其版本&#xff0c;便于其他开发者或自动化工具快速安装和更新这些依赖。元数据描述&#xff1a;提供项目的描述、作者、许可证等元信息&#xff0c;有助于项目的管理和维护。…...

docker-高级(待补图)

文章目录 数据卷(Volume)介绍查看方法删除方法绑定方法匿名绑定具名绑定Bind Mount 数据卷管理 网络bridge(桥接模式 默认)HOST(主机模式)Nonecontainer(指定一个容器进行关联网络共享)自定义(推荐)docker network 命令创建网络docker network create 实例展示-自定义实例展示-…...

Qt 文件目录操作

Qt 文件目录操作 QDir 类提供访问系统目录结构 QDir 类提供对目录结构及其内容的访问。QDir 用于操作路径名、访问有关路径和文件的信息以及操作底层文件系统。它还可以用于访问 Qt 的资源系统。 Qt 使用“/”作为通用目录分隔符&#xff0c;与“/”在 URL 中用作路径分隔符…...

Pandas 数据清洗

1.数据清洗定义 数据清洗是对一些没有用的数据进行处理的过程。很多数据集存在数据缺失、数据格式错误、错误数据或重复数据的情况&#xff0c;如果要使数据分析更加准确&#xff0c;就需要对这些没有用的数据进行处理。 2.清洗空值 DataFrame.dropna(axis0, howany, threshN…...

IO学习笔记

当前需求&#xff0c;希望进行游戏可以保存游戏进度&#xff0c;可以将游戏的进度保存到一个文本文件&#xff0c;每一次打完游戏更新文本内容&#xff0c;下一次打游戏读取游戏进度&#xff0c;这里就涉及到两个知识IO流和File的知识。 File类 概述 java.io.File 类是文件…...

汇编练习-1

1、要求 练习要求引自《汇编语言-第4版》实验10.3(P209页) -编程&#xff0c;将data段中的数据&#xff0c;以10进制的形式显示出来 data segment dw 123,12666,1,8,3,38 data ends 2、实现代码(可惜没找到csdn对8086汇编显示方式) assume cs:codedata segmentdw 16 dup(0) ;除…...

初识二叉树( 二)

初识二叉树 二 实现链式结构二叉树前中后序遍历遍历规则代码实现 结点个数以及高度等层序遍历判断是否为完全二叉树 实现链式结构二叉树 ⽤链表来表示⼀棵二叉树&#xff0c;即用链来指示元素的逻辑关系。通常的方法是链表中每个结点由三个域组成&#xff0c;数据域和左右指针…...

AcWing1077-cnblog

问题背景 给定一个树形结构的图&#xff0c;每个节点代表一个地点&#xff0c;每个节点有一个守卫的代价。我们希望以最低的代价在树的节点上放置守卫&#xff0c;使得整棵树的所有节点都被监控。可以通过三种方式覆盖一个节点&#xff1a; 由父节点监控。由子节点监控。自己…...

五、SpringBoot3实战(1)

一、SpringBoot3介绍 1.1 SpringBoot3简介 SpringBoot版本&#xff1a;3.0.5 https://docs.spring.io/spring-boot/docs/current/reference/html/getting-started.html#getting-started.introducing-spring-boot 到目前为止&#xff0c;你已经学习了多种配置Spring程序的方式…...

练习LabVIEW第三十三题

学习目标&#xff1a; 刚学了LabVIEW&#xff0c;在网上找了些题&#xff0c;练习一下LabVIEW&#xff0c;有不对不好不足的地方欢迎指正&#xff01; 第三十三题&#xff1a; 用labview编写一个判断素数的程序 开始编写&#xff1a; LabVIEW判断素数&#xff0c;首先要搞…...

如何在服务器端对PDF和图像进行OCR处理

介绍 今天我想和大家分享一个我在研究技术资料时发现的很好玩的东西——Tesseract。这不仅仅是一个普通的库&#xff0c;而是一个用C语言编写的OCR神器&#xff0c;能够识别一大堆不同国家的语言。我一直在寻找能够处理各种文档的工具&#xff0c;而Tesseract就像是给了我一把…...

Windows 下实验视频降噪算法 MeshFlow 详细教程

MeshFlow视频降噪算法 Meshflow 视频降噪算法来自于 2017 年电子科技大学一篇高质量论文。 该论文提出了一个新的运动模型MeshFlow&#xff0c;它是一个空间平滑的稀疏运动场 (spatially smooth sparse motion field)&#xff0c;其运动矢量 (motion vectors) 仅在网格顶点 (m…...

Python入门:如何正确的控制Python异步并发量(制并发量的关键技巧与易错点解析)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 异步并发量控制 📒📝 Python异步并发简介📝 为什么要限制并发量🎈 资源管理🎈 服务稳定性📝 新手容易犯的错误🎈 忽略并发量限制🎈 错误设置并发量📝 设置并发量要注意的事情🎈 了解任务类型🎈 考虑系统资…...

qt QCheckBox详解

QCheckBox 是 Qt 框架中的一个控件&#xff0c;用于创建复选框&#xff0c;允许用户进行选择和取消选择。它通常用于表单、设置界面和任何需要用户选择的场景。 QCheckBox继承自QAbstractButton类&#xff0c;因此继承了按钮的特性。它表示一个复选框&#xff0c;用户可以通过…...

PAT甲级-1041 Be Unique

题目 题目大意 从一组数字中选出第一个唯一出现的数&#xff0c;输出该数。如果没有&#xff0c;则输出None。 思路 哈希的思想&#xff0c;将数值作为索引&#xff0c;对应该数值出现的次数&#xff0c;然后遍历数组即可。 注意第一个数字是指数字的个数&#xff0c;不是数…...

【jvm】如何设置堆内存大小

目录 1. 使用命令行参数设置2. idea中设置3. 注意事项 1. 使用命令行参数设置 1.在Java命令后添加-Xms和-Xmx参数。2.-Xms参数用于设置JVM的初始堆内存大小&#xff0c;等价于-XX:InitialHeapSize。3.-Xmx参数用于设置JVM的最大堆内存大小&#xff0c;等价于-XX:MaxHeapSize。…...

kernel源码分析 do_msgsnd read_msg

笔者分析的源码是v 5.11.22 链接&#xff1a;msg.c - ipc/msg.c - Linux source code v5.11.22 - Bootlin do_msgsnd static long do_msgsnd(int msqid, long mtype, void __user *mtext,size_t msgsz, int msgflg) {struct msg_queue *msq;struct msg_msg *msg;int err;str…...

掌握 CTE 技巧,实现连续日期和月份的 SQL 报表统计

在 SQL 查询中&#xff0c;报表统计往往涉及到特定时间段内的数据汇总&#xff0c;如每日、每月的销售数据等。然而&#xff0c;面对缺少数据的日期或月份&#xff0c;传统 SQL 查询可能会直接跳过这些日期&#xff0c;使得输出的报表在视觉上并不连续。本文将展示如何利用 CTE…...

【表格解决问题】EXCEL行数过多,WPS如何按逐行分别打印多个纸张中

1 问题描述 如图&#xff1a;我的表格行数太多了。打印在一张纸上有点不太好看 2 解决方式 Step01&#xff1a;先选中你需要打印的部分&#xff0c;找到【页面】->【打印区域】->【设置打印区域】 Step02&#xff1a;先选中一行&#xff0c;找到【插入分页符】 Step0…...

Maven讲解从基础到高级配置与实践

一、基础认知 1.1 Maven 的主要作用 Maven 主要是用来管理 Java 项目构建流程的工具&#xff0c;包括以下几个方面&#xff1a; 依赖管理&#xff1a;通过 POM.xml 文件管理项目的外部依赖库&#xff0c;不同版本的依赖包可以通过 Maven 中央仓库自动下载&#xff0c;减少了…...

Vue3组件式父子传值

下面是使用 <script setup> 语法的 Vue 3 组件之间传值的示例。 示例 1:使用 Props 和 Emits 父组件 <template><div><h1>父组件</h1><ChildComponent :message="parentMessage" @reply="handleReply" /><p>…...

网页自动化测试和爬虫:Selenium库入门与进阶

网页自动化测试和爬虫&#xff1a;Selenium库入门与进阶 在现代Web开发和数据分析中&#xff0c;自动化测试和数据采集成为了开发流程中的重要部分。Python 的 Selenium 库是一种强大的工具&#xff0c;不仅用于网页自动化测试&#xff0c;也在网页爬虫中得到了广泛的应用。本…...

Cells 单元

Goto Data Grid 数据网格 Cells 单元 Content Alignment 内容对齐 显示数值的数据网格单元格会将其内容向右对齐。显示其他类型数据的单元格将其内容向左排列。若要更改单元格内容对齐方式&#xff0c;请处理 ColumnView.RowCellDefaultAlignment 事件。 Selection Modes 选…...

2024/11/2 安卓创建首页界面

‌Gradle 8.7 bin‌是指Gradle 8.7版本的二进制包&#xff0c;通常以.zip或.tar.gz格式提供。这个二进制包包含了运行Gradle所需的所有文件&#xff0c;用户可以直接下载并解压使用&#xff0c;无需从源代码编译。 首先了解最常用的布局 线性布局&#xff08;从上到下&#x…...

SpringSession源码分析

默认对常规Session的理解和使用&#xff0c;如何使用Set-Cookie。 Maven库 常见的spring-session-data-redis依赖spring-session-core <dependency><groupId>org.springframework.session</groupId><artifactId>spring-session-core</artifactId&…...