【机器视觉】yolo-world-opencvsharp-.net4.8 C# 窗体应用程序

news2024/11/15 17:58:48

47bc49fe5390f5be826993fad8765be4.png

这段代码是基于 OpenCvSharp, OpenVinoSharp 和 .NET Framework 4.8 的 Windows Forms 应用程序。其主要目的是加载和编译机器学习模型,对输入数据进行推理,并显示结果。

下面是该程序的主要功能和方法的详细总结:

  1. 初始化 OpenVINO 运行时核心(Core)和设备列表

  • 在 Form1_Load 方法中,程序创建了 Core 类的实例,并获取了可用设备列表,然后将这些设备添加到下拉选择框中。

选择模型和输入文件:

  • 使用 OpenFileDialog 来引导用户选择模型文件和输入文件(图片或视频)。btn_select_model_Click 和 btn_select_input_Click 方法负责处理文件选择对话框,并更新文本框以显示所选文件的路径。

加载并编译模型:

  • btn_load_model_Click 方法中,程序通过 read_model 方法加载用户选定的模型,然后调用 compile_model 方法将模型编译到指定设备上。编译完成后,创建了对模型的推理请求(InferRequest)。

执行推理:

  • btn_infer_Click 方法负责执行推理过程。它根据输入路径(图片或视频)调用 image_predict 方法来处理数据,并显示预测结果。

处理图片并推理:

  • image_predict 方法接受一个 Mat 图像,将其调整大小、归一化,并通过排列(Permutation)转换成模型所需的输入格式。之后,程序执行推理请求,并获取输出tensor。

后处理推理结果并显示:

  • postprocess 方法接受推理结果作为一个浮点数数组,根据设定的类别数和因子对结果进行预处理,检测出物体的矩形框,过滤和非极大值抑制(NMS)后,识别出类别和置信度,最终,将识别出的对象和对应信息绘制在图像上。

显示 FPS 和预测结果:

  • 推理后,程序计算并显示当前的帧率(FPS),并将检测框和标签绘制在结果图像上,并在界面中更新 pictureBox2 控件来展示图像。

该程序是由几个部分组成的一个界面应用,通过读取模型文件、处理图像和视频输入、执行模型推理,并在界面上展示结果的流程,体现了一种典型的实时物体检测和分类的机器学习应用。

// 引入OpenCvSharp相关的命名空间,用于图像处理和计算机视觉
using OpenCvSharp;
// 引入OpenCvSharp的Dnn(深度神经网络)命名空间,用于深度学习模型的加载和推理
using OpenCvSharp.Dnn;
// 引入OpenVinoSharp命名空间,用于模型优化和推理加速
using OpenVinoSharp;
// 引入OpenVinoSharp的Extensions下的model命名空间,包含模型加载和处理的扩展方法
using OpenVinoSharp.Extensions.model;
// 引入OpenVinoSharp的Extensions下的process命名空间,包含图像预处理的扩展方法
using OpenVinoSharp.Extensions.process;
// 引入OpenVinoSharp的Extensions下的result命名空间,包含推理结果处理的扩展方法
using OpenVinoSharp.Extensions.result;
// C#系统命名空间,提供基础类和基本函数
using System;
// 系统集合命名空间,提供用于创建集合的类
using System.Collections.Generic;
// 系统IO命名空间,用于处理文件输入输出
using System.IO;
// 系统网络命名空间,包含用于网络检测的类
using System.Net.NetworkInformation;
// 系统运行时互操作命名空间,包含访问和控制未经管理资源的类
using System.Runtime.InteropServices;
// 系统线程命名空间,用于多线程编程
using System.Threading;
// 系统Windows.Forms命名空间,包含创建Windows窗体应用程序的类
using System.Windows.Forms;


// 定义命名空间yolo_world_opencvsharp_net4._8
namespace yolo_world_opencvsharp_net4._8
{
    // Form1的部分类实现,继承于Form类
    public partial class Form1 : Form
    {
        // 声明与OpenVINO有关的变量
        public Core core = null; // 核心对象,用于管理OpenVINO的核心功能
        public Model model = null; // 模型对象,代表加载的神经网络模型
        public CompiledModel compiled_model = null; // 编译后的模型对象
        public InferRequest request = null; // 推理请求对象,用于执行推理
        // 声明时间统计用的变量
        DateTime start = DateTime.Now; // 记录开始时间
        DateTime end = DateTime.Now; // 记录结束时间
        // 类别名称列表,存储类别名称
        public List<string> classes = null;
        
        // Form1的构造函数
        public Form1()
        {
            // 初始化Form组件
            InitializeComponent();
        }
        
        // Form1加载时的事件处理函数
        private void Form1_Load(object sender, EventArgs e)
        {
            // 记录开始时间
            start = DateTime.Now;
            // 创建OpenVINO核心对象
            core = new Core();
            // 记录结束时间
            end = DateTime.Now;
            // 在文本框中输出初始化OpenVINO运行时核心的时间
            tb_msg.AppendText("Initialize OpenVINO Runtime Core: " + (end - start).TotalMilliseconds + "ms.\r\n");
            // 获取可用的设备列表
            List<string> devices = core.get_available_devices();
            // 遍历设备列表,将设备添加到下拉选择框中
            foreach (var item in devices)
            {
                cb_device.Items.Add(item);
            }
            // 选定下拉框的第一个设备作为默认选择
            cb_device.SelectedIndex = 0;
        }


        // 选择模型按钮点击时的事件处理函数
        private void btn_select_model_Click(object sender, EventArgs e)
        {
            // 创建文件选择对话框对象
            OpenFileDialog dlg = new OpenFileDialog();
            // 设置对话框标题
            dlg.Title = "选择推理模型文件";
            // 设置文件过滤器,只显示特定的模型文件格式
            dlg.Filter = "模型文件(*.pdmodel,*.onnx,*.xml)|*.pdmodel;*.onnx;*.xml";
            // 显示对话框,并判断用户是否点击了“确定”
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                // 将用户选择的文件路径显示在文本框中
                tb_model_path.Text = dlg.FileName;
            }
        }


        // 选择输入按钮点击时的事件处理函数
        private void btn_select_input_Click(object sender, EventArgs e)
        {
            // 创建文件选择对话框对象
            OpenFileDialog dlg = new OpenFileDialog();
            // 设置对话框标题
            dlg.Title = "选择测试输入文件";
            // 设置文件过滤效果,只显示图片和视频文件
            dlg.Filter = "图片文件(*.png,*.jpg,*.jepg,*.mp4)|*.png;*.jpg;*.jepg;*.mp4";
            // 显示对话框,并判断用户是否点击了“确定”
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                // 将用户选择的文件路径显示在文本框中
                tb_input_path.Text = dlg.FileName;
            }
        }
        
        // 加载模型按钮点击时的事件处理函数
        private void btn_load_model_Click(object sender, EventArgs e)
        {
            //省略前文已详述的代码,此处直接呈现未注释部分的译文:
            // 读取推理模型
            model = core.read_model(tb_model_path.Text);
            // 将模型加载到指定设备中
            compiled_model = core.compile_model(model, cb_device.SelectedItem.ToString());
            // 创建推理请求
            request = compiled_model.create_infer_request();
        }


        // 推理按钮点击时的事件处理函数
        private void btn_infer_Click(object sender, EventArgs e)
        {
            //省略前文已详述的代码,此处直接呈现未注释部分的译文:
            // 如果输入路径的扩展名为.mp4,则处理视频,否则处理图像
            if (Path.GetExtension(tb_input_path.Text) == ".mp4")
            {
                // 创建视频捕获对象,并处理视频中的每一帧
                VideoCapture video = new VideoCapture(tb_input_path.Text);
                if (video.IsOpened()) 
                {
                    Mat frame = new Mat();
                    video.Read(frame);
                    // 循环读取视频帧并进行预测处理,直到视频帧为空
                    while (!frame.Empty())
                    {
                        image_predict(frame);
                        video.Read(frame);
                        Thread.Sleep(10);
                    }
                }
            }
            else 
            { 
                // 读取图像文件并进行预测处理
                Mat image = Cv2.ImRead(tb_input_path.Text); 
                image_predict(image); 
            }
        }
        
        // 图像预测函数
        void image_predict(Mat image) 
        {
            // 省略前文的详细代码部分,此处直接呈现未注释部分的译文:
            // 将图像数据预处理并设置到推理请求的输入张量中,然后执行推理
            Tensor input_tensor = request.get_input_tensor();
            Shape input_shape = input_tensor.get_shape();
            // 省略图像预处理代码
            request.infer();
            // 获取输出张量,并处理预测结果
            Tensor output_tensor = request.get_output_tensor();
            Shape output_shape = output_tensor.get_shape();
            // 从输出张量中获取结果,并执行后处理计算
            float[] result_data = output_tensor.get_data<float>((int)output_tensor.get_size());
        }
        
        // 后处理结果函数
        DetResult postprocess(float[] result, int categ_nums, float factor) 
        {
            // 省略前文的详细代码部分,以下是一些关键未注释的译文:
            // 通过输出结果创建Mat对象
            Mat result_data = new Mat(4 + categ_nums, 8400, MatType.CV_32F,result);
            result_data = result_data.T();
            // 存储结果数据的列表
            List<Rect> position_boxes = new List<Rect>();
            List<int> classIds = new List<int>();
            List<float> confidences = new List<float>();
            // 循环处理输出数据
            for (int i = 0; i < result_data.Rows; i++)
            {
                // 省略输出数据的预处理代码
                // 如果置信度大于0.25,则存储结果数据
                if (maxScore > 0.25)
                {
                    // 省略计算检测框位置和尺寸的代码
                    Rect box = new Rect();
                    position_boxes.Add(box);
                    classIds.Add(maxClassIdPoint.X);
                    confidences.Add((float)maxScore);
                }
            }
            // 执行非最大抑制算法,过滤掉冗余的检测框
            int[] indexes = new int[position_boxes.Count];
            // 省略非最大抑制算法的代码
            // 根据索引,获取最终的检测结果
            DetResult re = new DetResult();
            return re;
        }
    }
}

本段代码是一个Windows窗体应用程序的部分实现,主要用于基于YOLO(You Only Look Once)算法的目标检测任务。应用程序使用OpenCvSharp和OpenVINO技术栈进行图像读取、模型推理和结果处理。代码涵盖了从初始化OpenVINO核心、模型加载、图像预处理到执行推理和结果显示的全过程。1. 初始化窗体组件并设置初始参数。2. 提供选择模型和测试输入文件的功能。3. 加载、编译模型以及创建推理请求。4. 实现对图像和视频的预测功能。5. 对推理结果进行后处理并在界面上显示检测框和类别信息。整个流程体现了使用机器学习模型进行图像识别和目标检测的完整过程。其中,重点应用了OpenCV库对图像进行处理和OpenVINO框架对模型进行优化和加速推理。这样的实现可以用于各种基于图像识别的应用场景,比如安全监控、交通管理等。

参考网址

1. https://docs.ultralytics.com/zh/integrations/onnx/ pt导出onnx

2313ead066f3df082b59de0c50849033.png

pt2onnx 会自动下载模型然后转格式

from ultralytics import YOLO


# Load the YOLOv8 model
model = YOLO('yolov8n.pt')
# model = YOLO('yolov8l-worldv2.pt')
# Export the model to ONNX format
model.export(format='onnx')  # creates 'yolov8n.onnx'


# Load the exported ONNX model
onnx_model = YOLO('yolov8n.onnx')
# onnx_model = YOLO('yolov8l-worldv2.onnx')
# Run inference
results = onnx_model('https://ultralytics.com/images/bus.jpg')

2. https://github.com/ultralytics/assets/releases 

3. https://github.com/ultralytics/ultralytics

4. https://github.com/AILab-CVC/YOLO-World/tree/master 

a0f19c7c238cd11f640fc089abc043e1.png

5. https://huggingface.co/spaces/stevengrove/YOLO-World

700a03b6699e1d74867abd33ce8c2b39.png

6. https://github.com/guojin-yan/OpenVINO-CSharp-API-Samples/tree/master

d128438b9f3da9dc27789e473e75587b.png

5952f7ca4fe33dc9e87a8acdf8256c36.png

2b0f7da915152d112900ab0de9236d34.png

  • 分类(Classify): 确定图像中的对象属于哪个类别。

  • 检测(Detect): 在图像中识别对象的位置并对其进行分类。

  • OBB(Oriented Bounding Box): 使用定向边界框来检测具有特定方向的对象。

  • 姿态(Pose): 估计图像中人或物体的姿态。

  • 分割(Segment): 将图像中的对象从背景中分离出来。

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

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

相关文章

【微服务】配置管理

Nacos配置管理 配置管理配置共享配置热更新 配置管理 将微服务集群中常用&#xff0c;经常变化的配置都写到一个独立的配置文件微服务中进行统一管理 配置共享 在Nacos的界面当中进行配置管理&#xff0c;在配置列表中添加配置 比如各个服务中的jdbc的连接配置&#xff1a; …

【AI工具声音克隆】——OpenVoice一键部署modelScope一键使用

一、声音/音色克隆简介 声音或音色克隆的原理实现步骤主要基于深度学习技术&#xff0c;特别是语音合成和生成模型。以下是声音/音色克隆的大致实现步骤&#xff1a; 数据收集&#xff1a; 收集语音数据&#xff0c;作为模型的训练样本。数据应尽可能多样化&#xff0c;包括不…

基于stm32的USB虚拟U盘+FATFS+W25Q64

基于stm32的USB虚拟U盘FATFSW25Q64 本文目标&#xff1a;基于stm32的USB虚拟U盘FATFSW25Q64 按照本文的描述&#xff0c;简单跑通USB的MSC类来进行简单交互。 先决条件&#xff1a;拥有C语言基础&#xff0c;装有编译和集成的开发环境&#xff0c;比如&#xff1a;Keil uVis…

如果还有机会再跟芒格共度一天,巴菲特想做什么?

这是芒格因离世而缺席的第一年&#xff0c;但他的身影却无处不在。问答环节&#xff0c;巴菲特会不小心脱口而出“查理&#xff0c;该你回答了”&#xff0c;他也称&#xff0c;与芒格在一起的时间比独处要快乐。 可以说&#xff0c;虽然99岁的芒格因离世而缺席了2024年伯克希…

记录几种排序算法

十种常见排序算法可以分类两大类别&#xff1a;比较类排序和非比较类排序。 常见的快速排序、归并排序、堆排序以及冒泡排序等都属于比较类排序算法。比较类排序是通过比较来决定元素间的相对次序&#xff0c;其时间复杂度不能突破 O(nlogn)。在冒泡排序之类的排序中&…

Python基础详解一

一&#xff0c;print打印 print("hello word") print(hello word) 双引号和单引号都可以 二&#xff0c;数据类型 Python中常用的有6种值的类型 输出类型信息 print(type(11)) print(type("22")) print(type(22.2)) <class int> <class str&…

Mybatis进阶2

Mybatis进阶1-CSDN博客 Mybatis入门-CSDN博客 Mybatis入门2-CSDN博客 我们接下来要学习Mybatis的高级查询 我们先在数据库中准备我们需要的数据表 teacher表 课程表&#xff1a;与教师表是一对多的关系&#xff0c;所以有一个外键字段 学生表 由于学生表和课程表是多对多的…

鸿蒙ArkTs开发,仿抖音个人中心header 下拉放大

如果是iOS 或者android 上实现&#xff0c;可以用Scollview 的contentOffset 来实现&#xff0c;然而在鸿蒙ets中该如何实现&#xff1f;废话不多说开始撸代码 第一步、实现一个header // 创建header&#xff0c;准备一张背景图片BuilderHeaderBuilder(){Column() {Row() {Ima…

算法入门<一>:C++各种排序算法详解及示例源码

1、排序算法 排序算法&#xff08;sorting algorithm&#xff09;用于对一组数据按照特定顺序进行排列。排序算法有着广泛的应用&#xff0c;因为有序数据通常能够被更高效地查找、分析和处理。 1.1 评价维度 运行效率&#xff1a;我们期望排序算法的时间复杂度尽量低&#xf…

C语言学习【C语言基本数据类型】

C语言学习【C语言基本数据类型】 整数溢出 /* 整数溢出 */ #include "stdio.h" /* Last Modified Time: 2024-05-05 17:53:49 */int main(void) {int i 2147483647;unsigned int j 4294967295;printf("%d %d %d\n", i, i1, i2);printf("%u %u %u\…

【数据结构初阶】直接插入排序

最近浅学了直接插入排序&#xff0c;写个博客做笔记&#xff01;笔记功能除外若能对读者老爷有所帮助最好不过了&#xff01; 直接插入排序是插入排序的一种&#xff0c;那么介绍直接插入排序之前先介绍一下常见的排序算法&#xff01; 目录 1.常见的排序算法 2.直接插入排…

500行代码实现贪吃蛇(1)

文章目录 目录1. Win32 API 介绍1.1 Win32 API1.2 控制台程序&#xff08;Console&#xff09;1.3 控制台屏幕上的坐标COORD1.4 [GetStdHandle](https://learn.microsoft.com/zh-cn/windows/console/getstdhandle)1.5 [GetConsoleCursorInfo](https://learn.microsoft.com/zh-c…

项目经理【人】原则

系列文章目录 【引论一】项目管理的意义 【引论二】项目管理的逻辑 【环境】概述 【环境】原则 【环境】任务 【环境】绩效 【人】概述 【人】原则 一、共创模式 1.1 共创模式 二、干系人的影响力强度和态度 2.1 干系人影响力 2.2 干系人态度 2.3 干系人管理 三、干系人权力…

Java17 --- SpringCloud之Gateway

目录 一、Gateway网关创建 1.1、创建微服务子工程9527及配置和依赖 1.1.1、pom依赖 1.1.2、yml配置 1.1.3、主启动类并测试入驻consul 二、实现路由映射 2.1、服务8001新增测试代码 2.2、修改9527服务yml配置文件 2.3、远程调用接口加gateway 2.3.1、新增80服务测…

【Android学习】简单的登录页面和业务逻辑实现

实现功能 1 登录页&#xff1a;密码登录和验证码登录 2 忘记密码页&#xff1a;修改密码 3 页面基础逻辑 java代码 基础页面 XML login_main.xml <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.and…

C++静态数组和C语言静态数组的区别( array,int a[])

目录 一、区别 1、越界读&#xff0c;检查不出来 2、越界写&#xff0c;抽查&#xff0c;可能检查不出来&#xff0c;有局限性 二、array缺点 一、区别 C语言的静态数组int a[]; 静态数组的越界检查不稳定的&#xff1a; 1、越界读&#xff0c;检查不出来 2、越界写&#x…

开发一款简易APP

希望打开APP后,显示当前时间..可能不实用,重在体验 安装Flutter 如果在arm架构的 Mac 电脑上进行开发&#xff0c;需要安装 Rosetta 2, 因为一些辅助工具需要&#xff0c;可通过手动运行下面的命令来安装&#xff1a; sudo softwareupdate --install-rosetta --agree-to-licens…

一篇文章带你深入了解“指针”

一篇文章带你深入了解“指针” 内存和地址了解指针指针类型const修饰指针指针的运算指针与整数之间的运算指针与指针之间的运算指针的关系运算 void* 指针传值调用和传址调用数组和指针的关系野指针野指针的形成原因规避野指针 二级指针字符指针指针数组数组指针数组传参一维数…

动态炫酷的新年烟花网页代码

烟花效果的实现可以采用前端技术&#xff0c;如HTML、CSS和JavaScript。通过结合动画、粒子效果等技术手段&#xff0c;可以创建出独特而炫目的烟花效果。同时&#xff0c;考虑到性能和兼容性&#xff0c;需要确保效果在各种设备上都能够良好运行。 效果显示http://www.bokequ.…

Transformer中的数据输入构造

文章目录 1. 文本内容2. 字典构造2.1 定义一个类用于字典构造2.2 拆分文本2.3 构造结果 3. 完整代码 1. 文本内容 假如我们有如下一段文本内容&#xff1a; Optics It is the branch of physics that studies the behaviour and properties of light . Optical Science 这段…