C# Onnx Yolov8 Detect 戴口罩检测

news2025/1/8 11:47:01

效果

项目

代码

using Microsoft.ML.OnnxRuntime;
using Microsoft.ML.OnnxRuntime.Tensors;
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Onnx_Yolov8_Detect
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
        string image_path = "";
        string startupPath;
        string classer_path;
        string model_path;

        DateTime dt1 = DateTime.Now;
        DateTime dt2 = DateTime.Now;

        Mat image;
        Mat result_image;

        SessionOptions options;
        InferenceSession onnx_session;
        Tensor<float> input_tensor;
        List<NamedOnnxValue> input_ontainer;
        IDisposableReadOnlyCollection<DisposableNamedOnnxValue> result_infer;
        DisposableNamedOnnxValue[] results_onnxvalue;

        Tensor<float> result_tensors;
        float[] result_array;
        float[] factors = new float[2];

        Result result;
        DetectionResult result_pro;
        StringBuilder sb = new StringBuilder();

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = fileFilter;
            if (ofd.ShowDialog() != DialogResult.OK) return;

            pictureBox1.Image = null;
            pictureBox2.Image = null;
            textBox1.Text = "";

            image_path = ofd.FileName;
            pictureBox1.Image = new Bitmap(image_path);
            image = new Mat(image_path);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            startupPath = Application.StartupPath + "\\model\\";

            model_path = startupPath + "mask.onnx";
            classer_path = startupPath + "lable.txt";

            // 创建输出会话
            options = new SessionOptions();
            options.LogSeverityLevel = OrtLoggingLevel.ORT_LOGGING_LEVEL_INFO;
            options.AppendExecutionProvider_CPU(0);// 设置为CPU上运行

            // 创建推理模型类,读取本地模型文件
            onnx_session = new InferenceSession(model_path, options);

            // 输入Tensor
            input_tensor = new DenseTensor<float>(new[] { 1, 3, 640, 640 });

            // 创建输入容器
            input_ontainer = new List<NamedOnnxValue>();

        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (image_path == "")
            {
                return;
            }
            textBox1.Text = "检查中,请稍等……";
            pictureBox2.Image = null;
            Application.DoEvents();

            //图片缩放
            image = new Mat(image_path);
            int max_image_length = image.Cols > image.Rows ? image.Cols : image.Rows;
            Mat max_image = Mat.Zeros(new OpenCvSharp.Size(max_image_length, max_image_length), MatType.CV_8UC3);
            Rect roi = new Rect(0, 0, image.Cols, image.Rows);
            image.CopyTo(new Mat(max_image, roi));

            factors[0] = factors[1] = (float)(max_image_length / 640.0);

            //将图片转为RGB通道
            Mat image_rgb = new Mat();
            Cv2.CvtColor(max_image, image_rgb, ColorConversionCodes.BGR2RGB);
            Mat resize_image = new Mat();
            Cv2.Resize(image_rgb, resize_image, new OpenCvSharp.Size(640, 640));

            //输入Tensor
            for (int y = 0; y < resize_image.Height; y++)
            {
                for (int x = 0; x < resize_image.Width; x++)
                {
                    input_tensor[0, 0, y, x] = resize_image.At<Vec3b>(y, x)[0] / 255f;
                    input_tensor[0, 1, y, x] = resize_image.At<Vec3b>(y, x)[1] / 255f;
                    input_tensor[0, 2, y, x] = resize_image.At<Vec3b>(y, x)[2] / 255f;
                }
            }

            //将 input_tensor 放入一个输入参数的容器,并指定名称
            input_ontainer.Add(NamedOnnxValue.CreateFromTensor("images", input_tensor));

            dt1 = DateTime.Now;
            //运行 Inference 并获取结果
            result_infer = onnx_session.Run(input_ontainer);
            dt2 = DateTime.Now;

            //将输出结果转为DisposableNamedOnnxValue数组
            results_onnxvalue = result_infer.ToArray();

            //读取第一个节点输出并转为Tensor数据
            result_tensors = results_onnxvalue[0].AsTensor<float>();

            result_array = result_tensors.ToArray();

            resize_image.Dispose();
            image_rgb.Dispose();

            result_pro = new DetectionResult(classer_path, factors);
            result = result_pro.process_result(result_array);
            result_image = result_pro.draw_result(result, image.Clone());

            if (!result_image.Empty())
            {
                pictureBox2.Image = new Bitmap(result_image.ToMemoryStream());
                sb.Clear();
                sb.AppendLine("推理耗时:" + (dt2 - dt1).TotalMilliseconds + "ms");
                sb.AppendLine("------------------------------");
                for (int i = 0; i < result.length; i++)
                {
                    sb.AppendLine(string.Format("{0}:{1},({2},{3},{4},{5})"
                        , result.classes[i]
                        , result.scores[i].ToString("0.00")
                        , result.rects[i].TopLeft.X
                        , result.rects[i].TopLeft.Y
                        , result.rects[i].BottomRight.X
                        , result.rects[i].BottomRight.Y
                        ));
                }
                textBox1.Text = sb.ToString();
            }
            else
            {
                textBox1.Text = "无信息";
            }
        }
      
    }
}

下载

源码下载

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

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

相关文章

如何通过命令行进入到mysql?

如何通过命令行进入到mysql&#xff1f; 首先进入到C盘mysql安装目录的bin文件夹&#xff0c;然后在这个文件夹下打开命令行窗口&#xff0c;如下图&#xff1a; 接着输入进入命令mysql -u root -p如下图&#xff1a; 可以发现输入连接命令之后需要让你输入mysql连接密码&am…

层序中序还原二叉树

题目&#xff1a; 样例&#xff1a; 输入 6 0 2 5 1 4 3 1 2 4 0 5 3 输出 0 2 1 4 5 3 思路&#xff1a; 这道题&#xff0c;核心思想就是 结合 层序遍历的性质&#xff0c;根据 中序来判断左右孩子是否存在。 前中后序的遍历实现&#xff0c;主要都是 递归的形式实现遍历…

如何使用Python给图片添加水印

目录 一、安装Pillow库 二、导入Pillow库和需要用到的模块 三、添加水印 四、调用函数并设置参数 五、需要注意的方面 总结 在Python中&#xff0c;我们可以使用Pillow库来处理图像&#xff0c;包括添加水印。Pillow是Python中最流行的图像处理库之一&#xff0c;它支持多…

Android中使用Glide加载圆形图像或给图片设置指定圆角

一、Glide加载圆形头像 效果 R.mipmap.head_icon是默认圆形头像 ImageView mImage findViewById(R.id.image);RequestOptions options new RequestOptions().placeholder(R.mipmap.head_icon).circleCropTransform(); Glide.with(this).load("图像Uri").apply(o…

canvas画布绘制线条样式:粗细,圆角,拐角等

线条的粗线 lineWidth是改变线条的粗线的&#xff0c;默认是一个像素&#xff1a; context.beginPath(); context.moveTo(20, 50); context.lineTo(280, 50); context.lineWidth1; context.stroke();// 如果这里没有beginPath 你猜猜这三条线的宽度分别是多少 context.beginP…

分享一下微信投票小游戏怎么做

微信投票小游戏是一种非常有趣和互动的社交体验&#xff0c;可以促进用户参与和互动&#xff0c;同时也可以为企业或个人带来很多好处。下面我们将探讨如何制作一个微信投票小游戏&#xff0c;以及如何为主题写作一篇文章。 一、确定游戏目的和主题 首先&#xff0c;我们需要确…

AWS Lambda – 函数版本,别名,API网关,CodeDeploy协同

Hello大家好&#xff0c;我们今天继续讨论AWS Lambda的内容。 Lambda函数的版本 Lambda函数的版本和别名是辅助资源&#xff0c;我们可以通过创建这些资源管理函数的部署和调用。 首先&#xff0c;让我们来看一下Lambda 函数版本的概念。您可以使用版本来管理函数的部署。例…

汽车屏类产品(三):抬头显示Head-Up Display(HUD)

前言 你的下一台车,一定要考虑加装一个HUD。 汽车抬头显示器或汽车抬头显示器(也称为汽车HUD)是任何透明的显示器,它可以在汽车中显示数据,而不需要用户将视线从平时的视角移开。这个名字的由来源于飞行员能够在头部“向上”并向前看的情况下查看信息,而不是向下倾斜查…

Unity3D 在做性能优化时怎么准确判断是内存、CPU、GPU瓶颈详解

Unity3D是一款广泛应用于游戏开发的跨平台游戏引擎&#xff0c;但在开发过程中&#xff0c;我们经常会遇到性能瓶颈问题&#xff0c;如内存、CPU和GPU瓶颈。本文将详细介绍在Unity3D中如何准确判断和解决这些瓶颈问题&#xff0c;并给出相应的技术详解和代码实现。 对惹&#…

干式电抗器的尺寸和重量对系统有什么影响?

干式电抗器的尺寸决定了它在系统中所占的空间大小&#xff0c;较大尺寸的电抗器需要更多的安装空间&#xff0c;可能会增加系统的体积和复杂性。干式电抗器的重量对系统的负荷和支撑结构有影响&#xff0c;较大重量的电抗器可能需要更强大的支撑结构和更稳固的安装方式&#xf…

若要对多态类进行深拷贝,应使用虚函数的clone,而不是公开的拷贝构造赋值

拷贝一个多态类可能会导致切片问题&#xff0c;为了解决这个问题&#xff0c;应覆盖一个虚clone函数&#xff0c;让他根据实际类型进行复制并返回一个到新对象的所有权的指针&#xff08;std::unique_ptr&#xff09;,在派生类&#xff0c;通过使用所谓的协变返回类型来返回派生…

2023年中国婴童护肤发展概况及趋势分析:婴童功能护肤产品成为新趋势[图]

我国婴童护肤行业相关法律法规逐步完善&#xff0c;推动儿童化妆品的生产与研发&#xff0c;降低消费者购买决策消耗与担忧&#xff1b;2021年10月发布的《儿童化妆品监督管理规定》明确规定儿童化妆品配方设计应当遵循功效必需原则。总的来说&#xff0c;各项政策助力跨境婴童…

为修复各种问题,iOS 17.1应运而生,那么它到底解决什么问题或带来什么功能呢

iOS 17即将进行第一次重大更新&#xff0c;iOS 17.1的候选版本现在掌握在开发人员和测试人员手中。这通常是即将全面释放的迹象。 事实上&#xff0c;我们对iOS 17.1更新何时应该停止有一个很好的想法&#xff0c;这要归功于法国监管机构的一份声明&#xff0c;该声明称即将对…

【Axure教程】多图表动态切换

不同类型的图表用于分析和呈现不同类型的数据&#xff0c;柱状图用于比较不同类别或组之间的数据&#xff1b;条形图用于显示数据的分布情况&#xff0c;特别是连续数据的频率分布&#xff1b;饼图和环形图用于表示各部分占整体的比例&#xff1b;折线图、曲线图和面积图用于显…

解决matlab报错“输入参数的数目不足”

报错语句&#xff1a;tanh((peakNums-parameter)/2) 报错提示&#xff1a;输入参数的数目不足 运行环境&#xff1a;matlab2021b 分析原因&#xff1a; 当执行peakNums - parameter时&#xff0c;如果peakNums和parameter都是向量&#xff0c;那么这并不一定意味着会得到对应…

HR9110S 单通道控制工作原理

HR9110是应用于直流电机方案的单通道H桥驱动器芯片。HR9110的H桥驱动部分采用低导通电阻的PMOS和NMOS功率管。当芯片温度超过温度阈值&#xff08;典型150℃&#xff09;&#xff0c;HR9110会关断所有的输出&#xff0c;防止潜在隐患。只有当确认了芯片回归到工作温度&#xff…

PTE-精听学习(四)

目录 精听练习方法 精听与数量无关&#xff0c;与质量有关 听到一两个单词&#xff0c;就可以默写整句话 出现了过去时&#xff0c;有时间的指示代词 表示原本以为 精听练习方法 精听与数量无关&#xff0c;与质量有关 听到一两个单词&#xff0c;就可以默写整句话 突然…

从入门到进阶 之 ElasticSearch SpringData 继承篇

&#x1f339; 以上分享 从入门到进阶 之 ElasticSearch SpringData 继承篇&#xff0c;如有问题请指教写。&#x1f339;&#x1f339; 如你对技术也感兴趣&#xff0c;欢迎交流。&#x1f339;&#x1f339;&#x1f339; 如有需要&#xff0c;请&#x1f44d;点赞&#x1f…

uniapp vue3 使用pinia存储 并获取数据

存token import { defineStore } from pinia;export const userInfo defineStore(userInfo, {state: () > {return {userToken: uni.getStorageSync(token) || ,};},actions: {// 添加tokenupdateToken(token: string) {uni.setStorageSync(token, token);this.userToken…

移动端1px-从基本原理到开源解决方案介绍

1px 不够准确&#xff0c;应该说成 1 物理像素 为什么有 1px 这个问题&#xff1f;实现 1px 有哪些方法&#xff1f;这些方法分别有哪些优缺点&#xff1f;开源项目中使用的哪些解决方案&#xff1f;如何在项目中处理 1px 的相关问题&#xff1f; 基本概念 首先&#xff0c;我们…