[C#]winform部署官方yolov10目标检测的onnx模型

news2024/11/17 7:43:35

【框架地址】

https://github.com/THU-MIG/yolov10
【算法介绍】

今天为大家介绍的是 YOLOv10,这是由清华大学研究团队最新提出的,同样遵循 YOLO 系列设计原则,致力于打造实时端到端的高性能目标检测器。

方法

创新

  1. 双标签分配策略

众所周知,标签分配策略对于目标检测器来说是至关重要的。经过这几年的发展,前前后后也提出了许多的不同的方案,但归根结底还是围绕着正负样本去定义。通常,我们会认为与 GT 框的 IoU 大于给定阈值的便是正样本

首先,回顾下经典的 YOLO 架构,其通过网格化的方式预定义数千个锚框(anchor),然后基于这些锚框进一步执行回归和分类任务。然而,实际场景中,我们所面临的目标其大小、长宽比、数量、位姿均各有所异,因此很难通过这种方式来提供一个完美的先验信息,尽管可以借助一些方法如 kmeans 聚类来获得一个次优的结果。

于是乎,基于 anchor-free 的目标检测器被提出来了。其标签分配策略被简化成了从网格点到目标框中心或者角点的距离。遗憾的是,无论是 anchor-based 的“框分配”策略还是 anchor-free 的“点分配”策略,其始终会面临一个 many-to-one 的窘境,即对于一个 GT 框来说,会存在多个正样本与之对应。

这便意味着 NMS 成为了一种必不可少的手段,以避免产生冗余检测框。然而,引入 NMS 一方面会增加耗时,同时也会引入一些问题,譬如当 IoU 设置不恰当时会导致一些高置信度的正确目标框被过滤掉(密集场景下)。

当然,针对这个问题,后面也提出了不少解决方案。如最容易想到的就是 two-stage 模型的 one-to-one 即一对一分配策略,我们强制只将一个 GT 框分配给一个正样本,这样就可以避免引入 NMS,可惜效率方面是个极大的劣势。

又比如 One-Net 提出的最小代价分配(Minimum Cost Assignment),即于每个 GT,仅将一个最小代价样本分配为正样本,其它均为负样本,该方法不涉及手动制定的启发式规则或者复杂的二分图匹配。这里代价是指样本与真值之间的分类代价和位置代价的总和。

另一方面,诸如 DETR 系列的检测器,其直接利用 Transformer 的全局建模能力,将目标检测看成是一个集合预测的问题。为了实现端到端的检测,其使用的标签分配策略是二分匹配,使得一个 GT 只能分配到一个正样本。

由于篇(知)幅(识)有(盲)限(区),今天我们就讲到这。回到今天的主角,YOLOv10 的一大创新点便是引入了一种双重标签分配策略,其核心思想便是在训练阶段使用一对多的检测头提供更多的正样本来丰富模型的训练;而在推理阶段则通过梯度截断的方式,切换为一对一的检测头,如此一来便不在需要 NMS 后处理,在保持性能的同时减少了推理开销。

原理其实不难,大家可以看下代码理解下:

#https://github.com/THU-MIG/yolov10/blob/main/ultralytics/nn/modules/head.py
class v10Detect(Detect):

    max_det = -1

    def __init__(self, nc=80, ch=()):
        super().__init__(nc, ch)
        c3 = max(ch[0], min(self.nc, 100))  # channels
        self.cv3 = nn.ModuleList(nn.Sequential(nn.Sequential(Conv(x, x, 3, g=x), Conv(x, c3, 1)), \
                                               nn.Sequential(Conv(c3, c3, 3, g=c3), Conv(c3, c3, 1)), \
                                                nn.Conv2d(c3, self.nc, 1)) for i, x in enumerate(ch))

        self.one2one_cv2 = copy.deepcopy(self.cv2)
        self.one2one_cv3 = copy.deepcopy(self.cv3)
    
    def forward(self, x):
        one2one = self.forward_feat([xi.detach() for xi in x], self.one2one_cv2, self.one2one_cv3)
        if not self.export:
            one2many = super().forward(x)

        if not self.training:
            one2one = self.inference(one2one)
            if not self.export:
                return {"one2many": one2many, "one2one": one2one}
            else:
                assert(self.max_det != -1)
                boxes, scores, labels = ops.v10postprocess(one2one.permute(0, 2, 1), self.max_det, self.nc)
                return torch.cat([boxes, scores.unsqueeze(-1), labels.unsqueeze(-1)], dim=-1)
        else:
            return {"one2many": one2many, "one2one": one2one}

    def bias_init(self):
        super().bias_init()
        """Initialize Detect() biases, WARNING: requires stride availability."""
        m = self  # self.model[-1]  # Detect() module
        # cf = torch.bincount(torch.tensor(np.concatenate(dataset.labels, 0)[:, 0]).long(), minlength=nc) + 1
        # ncf = math.log(0.6 / (m.nc - 0.999999)) if cf is None else torch.log(cf / cf.sum())  # nominal class frequency
        for a, b, s in zip(m.one2one_cv2, m.one2one_cv3, m.stride):  # from
            a[-1].bias.data[:] = 1.0  # box
            b[-1].bias.data[: m.nc] = math.log(5 / m.nc / (640 / s) ** 2)  # cls (.01 objects, 80 classes, 640 img)
  1. 架构改进

  • Backbone & Neck:使用了先进的结构如 CSPNet 作为骨干网络,和 PAN 作为颈部网络,优化了特征提取和多尺度特征融合。
  • 大卷积核与分区自注意力:这些技术用于增强模型从大范围上下文中学习的能力,提高检测准确性而不显著增加计算成本。
  • 整体效率:引入空间-通道解耦下采样和基于秩引导的模块设计,减少计算冗余,提高整体模型效率。

这块没啥好讲的,大家看一眼框架图便清楚了,懂的都懂。:)

性能

YOLOv10 在各种模型规模上显示了显著的性能和效率改进。关键比较包括:

  • YOLOv10-S vs. RT-DETR-R18:YOLOv10-S 的速度提高了 1.8 倍,同时在 COCO 数据集上保持类似的平均精度(AP),参数和 FLOPs 分别减少了 2.8 倍。
  • YOLOv10-B vs. YOLOv9-C:YOLOv10-B 的延迟减少了 46%,参数减少了 25%,而性能相当。

扩展性

ModelTest Size#ParamsFLOPsAPvalLatency
YOLOv10-N6402.3M6.7G38.5%1.84ms
YOLOv10-S6407.2M21.6G46.3%2.49ms
YOLOv10-M64015.4M59.1G51.1%4.74ms
YOLOv10-B64019.1M92.0G52.5%5.74ms
YOLOv10-L64024.4M120.3G53.2%7.28ms
YOLOv10-X64029.5M160.4G54.4%10.70ms

YOLOv10 提供了多个模型规模(N、S、M、B、L、X),允许用户根据性能和资源约束选择最适合的模型。这种可扩展性确保了 YOLOv10 能够有效应用于各种实时检测任务,从移动设备上的轻量级应用到需要高精度的复杂任务。

实验

这里重点看下表3,可以看出,采用一对多的检测头性能最好(提供了更丰富的正样本监督信号),但延迟也高了许多(需要 NMS 做后处理);另外方面,一对一的检测头则性能会稍微下降,但延迟却低了不少;最终综合利用两者的优势能达到一个最优的精度-速度折衷。

【效果展示】

【部分实现代码】

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using OpenCvSharp;

namespace FIRC
{
    public partial class Form1 : Form
    {
        Mat src = new Mat();
        Yolov10Manager ym = new Yolov10Manager();
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "图文件(*.*)|*.jpg;*.png;*.jpeg;*.bmp";
            openFileDialog.RestoreDirectory = true;
            openFileDialog.Multiselect = false;
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
              
                src = Cv2.ImRead(openFileDialog.FileName);
                pictureBox1.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(src);


            }


        }

        private void button2_Click(object sender, EventArgs e)
        {
            if(pictureBox1.Image==null)
            {
                return;
            }
            Stopwatch sw = new Stopwatch();
            sw.Start();
            var result = ym.Inference(src);
            sw.Stop();
            this.Text = "耗时" + sw.Elapsed.TotalSeconds + "秒";
            var resultMat = ym.DrawImage(result,src);
            pictureBox2.Image= OpenCvSharp.Extensions.BitmapConverter.ToBitmap(resultMat); //Mat转Bitmap
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            ym.LoadWeights(Application.StartupPath+ "\\weights\\yolov10n.onnx", Application.StartupPath + "\\weights\\labels.txt");

        }

        private void btn_video_Click(object sender, EventArgs e)
        {
            var detector = new Yolov10Manager();
            detector.LoadWeights(Application.StartupPath + "\\weights\\yolov10n.onnx", Application.StartupPath + "\\weights\\labels.txt");
            VideoCapture capture = new VideoCapture(0);
            if (!capture.IsOpened())
            {
                Console.WriteLine("video not open!");
                return;
            }
            Mat frame = new Mat();
            var sw = new Stopwatch();
            int fps = 0;
            while (true)
            {

                capture.Read(frame);
                if (frame.Empty())
                {
                    Console.WriteLine("data is empty!");
                    break;
                }
                sw.Start();
                var result = detector.Inference(frame);
                var resultImg = detector.DrawImage(result,frame);
                sw.Stop();
                fps = Convert.ToInt32(1 / sw.Elapsed.TotalSeconds);
                sw.Reset();
                Cv2.PutText(resultImg, "FPS=" + fps, new OpenCvSharp.Point(30, 30), HersheyFonts.HersheyComplex, 1.0, new Scalar(255, 0, 0), 3);
                //显示结果
                Cv2.ImShow("Result", resultImg);
                int key = Cv2.WaitKey(10);
                if (key == 27)
                    break;
            }

            capture.Release();
  
        }
    }
}

【视频演示】

C# winform部署yolov10的onnx模型_哔哩哔哩_bilibiliC#部署yolov10官方onnx模型,首先转成Onnx模型然后即可调用。测试环境:vs2019netframework4.7.2onnxruntime1.16.3opencvsharp==4.8.0, 视频播放量 1、弹幕量 0、点赞数 0、投硬币枚数 0、收藏人数 0、转发人数 0, 视频作者 未来自主研究中心, 作者简介 未来自主研究中心,相关视频:我的开源代码居然被盗去卖钱?AI文字搜图搜视频,语义搜索新版整合包发布!,yolov10 tensorrt C++ 推理!全网首发!,C++使用纯opencv部署yolov9的onnx模型,重生紫薇之:容嬷嬷带我了解yolo v10! ----人工智能/计算机视觉/yolo,起猛了,一觉起来看到YOLOv10都发布了!我看看是谁还在研究yolov123456789的,C#YOLO工业滑轨螺丝缺失检测~示例,将yolov5-6.2封装成一个类几行代码完成语义分割任务,毕设项目—基于最新YOLOv10+ByteTrack+PaddleOCR实现交通状态分析 (功能:目标检测、轨迹跟踪、车牌检测、车牌号识别、单目测速及目标计数),labelme json转yolo工具用于目标检测训练数据集使用教程,将yolov8封装成一个类几行代码完成语义分割任务icon-default.png?t=N7T8https://www.bilibili.com/video/BV111421173R/?vd_source=989ae2b903ea1b5acebbe2c4c4a635ee

【测试环境】

vs2019,netframework4.7.2,onnxruntime1.16.3,opencvsharp4.8.0

【源码下载】

https://download.csdn.net/download/FL1623863129/89366968

【参考文献】

1 https://zhuanlan.zhihu.com/p/699842844

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

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

相关文章

shell脚本-函数

一、函数 1.函数的定义和格式 函数定义:封装的可重复利用的具有特定功能的代码 先定义函数,再调用函数,注意顺序 函数类似于命令的别名,别名一些简单的小命令 函数是某一个脚本的别名,有些脚本会重复使用 函数格…

【链表】Leetcode 92. 反转链表 II【中等】

反转链表 II 给你单链表的头指针 head 和两个整数 left 和 right &#xff0c;其中 left < right 请你反转从位置 left 到位置 right 的链表节点&#xff0c;返回 反转后的链表 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], left 2, right 4 输出&#x…

【一刷《剑指Offer》】面试题 24:二叉搜索树的后序遍历系列

力扣对应题目链接&#xff1a;LCR 152. 验证二叉搜索树的后序遍历序列 - 力扣&#xff08;LeetCode&#xff09; 牛客对应题目链接&#xff1a;二叉搜索树的后序遍历序列_牛客题霸_牛客网 (nowcoder.com) 核心考点 &#xff1a; BST 特征的理解。 一、《剑指Offer》对应内容 二…

NASA数据集——严格校准的臭氧(O3)、甲醛(HCHO)、二氧化碳(CO2)和甲烷(CH4)混合比,以及包括三维风在内的气象数据

Alpha Jet Atmopsheric eXperiment Meteorological Measurement System (MMS) Data 阿尔法喷气式大气实验气象测量系统&#xff08;MMS&#xff09;数据 简介 Alpha Jet Atmospheric eXperiment (AJAX) 是美国国家航空航天局艾姆斯研究中心与 H211, L.L.C. 公司的合作项目&a…

LAMP网络服务架构

目录 LAMP 网站服务架构 LAMP的组成部分 LAMP的构建顺序 安装论坛 0.电脑已编译安装Apache&#xff0c;MySQL&#xff0c;PHP 1.创建数据库&#xff0c;并进行授权 2.上传论坛压缩包到 /opt ,并解压 3.上传站点更新包 4.更改论坛目录的属主 5.浏览器访问验证 LAMP 网…

2024年03月 Python(四级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,共50分) 第1题 运行如下代码,若输入整数3,则最终输出的结果为?( ) def f(x):if x==1:s=1else:s

各种情况下的线缆大小选择

开口线鼻子和导线对应大小 开口铜鼻子对应线径大小 变压器容量对应高压侧电流大小 开关电流线缆功率对照表 家庭/工业最常用电线铜线电流承载功率 电工常用名词对应符号 导线面积承载的安全载流量及允许负荷对照表 漏电保护器选择参考表 电动机功率换算电流 电机功…

应用程序中的会话管理和Cookie安全指南

应用程序中的会话管理和Cookie安全指南 在现代应用程序中&#xff0c;会话管理和Cookie安全是确保用户信息和数据安全的重要组成部分。本文将详细介绍会话管理的最佳实践以及如何通过安全的Cookie设置来保护会话ID的交换。 单点登录&#xff08;SSO&#xff09;及会话管理机制…

其二:使用递归法实现二分搜索

开篇 本文主要是利用递归法来实现一个简单的二分搜索程序。题目来源是《编程珠玑》第4章课后习题3。 问题概要 编写并验证一个递归的二分搜索程序, 并返回t在数组x[0…n-1]中第一次出现的位置。 思路分析 本题的思路与第一版相似&#xff0c;不过不同的是&#xff0c;为确保返回…

Android 通过布局生成图片

通过布局生成图片 首先效果图 在竖屏的情况下通过&#xff0c;一般情况下&#xff0c;只要布局在页面上可见&#xff0c;并显示全&#xff0c;通过布局生成图片&#xff0c;都可以&#xff0c;但是横屏就不行了&#xff0c;会出现图片显示不完全的情况。 val bitmap Bitmap.c…

KingbaseES数据库物理备份还原sys_rman

数据库版本&#xff1a;KingbaseES V008R006C008B0014 简介 sys_rman 是 KingbaseES 数据库中重要的物理备份还原工具&#xff0c;支持不同类型的全量备份、差异备份、增量备份&#xff0c;保证数据库在遇到故障时及时使用 sys_rman 来恢复到数据库先前状态。 文章目录如下 1.…

Laravel和ThinkPHP框架比较

一、开发体验与易用性比较 1. 代码可读性&#xff1a; - Laravel以其优雅的语法和良好的代码结构著称&#xff0c;使得代码更加易读易懂。 - 相比之下&#xff0c;ThinkPHP的代码可读性较为一般&#xff0c;在一些复杂业务场景下&#xff0c;可能会稍显混乱。 让您能够一站式…

【leetcode 141】环形链表——快慢指针(龟兔赛跑)

给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置&#xff08;…

浙江大学数据结构MOOC-课后习题-第六讲-图2 Saving James Bond - Easy Version

题目汇总 浙江大学数据结构MOOC-课后习题-拼题A-代码分享-2024 题目描述 测试点 思路分享 ①解题思路概览 我的想法是&#xff0c;先建立一个图&#xff0c;然后再利用DFS或者BFS来遍历判断当前顶点能否跳到岸上去 ②怎么建图&#xff1f; 首先要考虑采用什么数据结构来存储图…

计算机网络导论

网络结构的演变 网状结构 最开始的网络&#xff0c;主机之间都是两两相连 好处 这样连接&#xff0c;好处是安全性比较高&#xff08;A与B之间的连线断了&#xff0c;可以绕一下C&#xff09;&#xff1b; 另外通信不需要互相等待&#xff08;没有中间交换设备&#xff0c;所…

yolov8+ROS+ubuntu18.04——学习记录

参考文献 1.Ubuntu配置Yolov8环境并训练自己的数据集 ROS实时运行 2.https://juejin.cn/post/7313979467965874214 前提&#xff1a; 1.CUDA和Anaconda&#xff0c;PyTorch 2.python>3.8 一、创建激活环境&#xff0c;安装依赖 1.创建虚拟环境 conda create -n yol…

【Qt Creator】跨平台的C++图形用户界面应用程序开发框架---QT

&#x1f341;你好&#xff0c;我是 RO-BERRY &#x1f4d7; 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f384;感谢你的陪伴与支持 &#xff0c;故事既有了开头&#xff0c;就要画上一个完美的句号&#xff0c;让我们一起加油 目录 1.互联网的核心岗位以及职…

一个基于预训练的DenseNet121模型的人脸年龄分类系统

这篇文章采用预训练的DenseNet121模型并使用自定义的数据集类和自定义的类似正态分布的标签平滑策略来训练了一个人脸年龄分类模型&#xff0c;最后基于这个模型用tk实现了一个娱乐向的小系统。 数据集展示&#xff1a; 两个文件夹&#xff0c;分别是训练集和测试集&#xff0…

空压机的热回收原理介绍

空压机运行时会产生大量的压缩热&#xff0c;通常这部分能量通过机组的风冷或水冷系统释放到大气当中。压缩机的热回收是持续降低空气系统损耗&#xff0c;提高客户生产力的必要手段。 余热回收的节能技术目前研究很多&#xff0c;但大多只针对喷油螺杆式空压机的油路改造而言…

【Linux】使用pip3安装pexpect,解决报错:the ssl module in Python is not available

pip3是python3的包管理工具&#xff0c;安装、卸载、更新等管理python包。 pexpect是其中一个python库&#xff0c;用于自动化与终端交互。 centos7使用pip3安装pexpect&#xff0c;报错&#xff1a; pip3 install pexpect 原因&#xff1a;使用python3解释器导入ssl库检查ss…