看图识熊(二)

使用Tools for AI封装onnx模型并推理

进行这一步之前,请确保已正确安装配置了Visual Studio 2017 和 Microsoft Visual Studio Tools for AI环境。

项目的代码也可以在这里找到,下面的步骤是带着大家从头到尾做一遍。

界面设计

创建Windows窗体应用(.NET Framework)项目,这里给项目起名ClassifyBear。

注意,项目路径不要包含中文。

在解决方案资源管理器中找到Form1.cs,双击,打开界面设计器。从工具箱中向Form中依次拖入控件并调整,最终效果如下图所示:

左侧从上下到依次是:

  • Label控件,将内容改为“输入要识别的图片地址:”

  • TextBox控件,可以将控件拉长一些,方便输入URL

  • Button控件,将内容改为“识别”

  • Lable控件,将label的内容清空,用来显示识别后的结果。因为label也没有边框,所以在界面看不出来。可以将此控件的字体调大一些,能更清楚的显示推理结果。

右侧的控件是一个PictureBox,用来预览输入的图片,同时,我们也从这个控件中取出对应的图片数据,传给我们的模型推理类库去推理。建议将控件属性的SizeMode更改为StretchImage,并将控件长和宽设置为同样的值,保持一个正方形的形状,这样可以方便我们直观的了解模型的输入,因为在前面查看模型信息的时候也看到了,该模型的输入图片应是正方形。

封装模型推理类库

由于目前模型推理用到的库只支持x64,所以这里需要将解决方案平台设置为x64。打开解决方案资源管理器,在解决方案上点右键,选择配置管理器。

在配置管理器对话框中,点开活动解决方案平台下拉框,选择新建

在新建解决方案平台对话框中,输入新平台名x64,点击确定即可

下面添加模型推理类库,再次打开解决方案资源管理器,在解决方案上点右键,选择添加,然后选择新建项目。

添加新项目对话框中,将左侧目录树切换到AI Tools下的Inference,右侧选择模型推理类库,下方填入项目名称,这里用Model作为名称。

确定以后会出现检查环境的进度条,耐心等待一会就可以出现模型推理类库创建向导对话框。

点击模型路径后面的浏览按钮,选择前面下载的BearModel.onnx模型文件。

注意,这里会出现几处错误提示,我们需要手动修复一下。首先会看到“发现不支持的张量的数据类型”提示,可以直接点确定。

确定后如果弹出“正在创建项目…”的进度条,一直不消失,这里只需要在类名后面的输入框内点一下,切换下焦点即可。

然后,我们来手动配置一下模型的相关信息。类名输入框中填入模型推理类的名字,这里用Bear。然后点击推理接口右侧的添加按钮,在弹出的编辑接口对话框中,随便起个方法名,这里用Infer。输入节点的变量名和张量名填入data,输出节点的变量名和张量名填入classLabel,字母拼写要和之前查看模型时看到的拼写一模一样。然后一路确定,再耐心等待一会,就可以在解决方案资源管理器看到新建的模型推理类库了。

至此,模型推理类库封装完成。

使用模型推理类库

首先添加对模型推理类库的引用,切换到解决方案资源管理器,在ClassifyBear项目的引用上点右键,选择添加引用。

在弹出的引用管理器对话框中,选择项目、解决方案,右侧可以看到刚刚创建的模型推理类库,勾选该项目,点击确定即可。

在Form1.cs上点右键,选择查看代码,打开Form1.cs的代码编辑窗口。

添加两个成员变量

// 使用Netron查看模型,得到模型的输入应为227*227大小的图片
private const int imageSize = 227;
​
// 模型推理类
private Model.Bear model;

回到Form1的设计界面,双击Form的标题栏,会自动跳转到代码页面并添加了Form1_Load方法,在其中初始化模型推理对象

private void Form1_Load(object sender, EventArgs e)
{// 初始化模型推理对象model = new Model.Bear();
}

回到Form1的设计界面,双击识别按钮,会自动跳转到代码页面并添加了button1_Click方法,在其中添加以下代码:

首先,每次点击识别按钮时都先将界面上显示的上一次的结果清除

// 识别之前先重置界面显示的内容
label1.Text = string.Empty;
pictureBox1.Image = null;
pictureBox1.Refresh();

然后,让图片控件加载图片

bool isSuccess = false;
try
{pictureBox1.Load(textBox1.Text);isSuccess = true;
}
catch (Exception ex)
{MessageBox.Show($"读取图片时出现错误:{ex.Message}");throw;
}

如果加载成功,将图片数据传给模型推理类库来推理。

if (isSuccess)
{// 图片加载成功后,从图片控件中取出227*227的位图对象Bitmap bitmap = new Bitmap(pictureBox1.Image, imageSize, imageSize);
​float[] imageArray = new float[imageSize * imageSize * 3];
​// 按照先行后列的方式依次取出图片的每个像素值for (int y = 0; y < imageSize; y++){for (int x = 0; x < imageSize; x++){var color = bitmap.GetPixel(x, y);
​// 使用Netron查看模型的输入发现// 需要依次放置227 *227的蓝色分量、227*227的绿色分量、227*227的红色分量imageArray[y * imageSize + x] = color.B;imageArray[y * imageSize + x + 1* imageSize * imageSize] = color.G;imageArray[y * imageSize + x + 2* imageSize * imageSize] = color.R;}}
​// 模型推理类库支持一次推理多张图片,这里只使用一张图片var inputImages = new List<float[]>();inputImages.Add(imageArray);
​// 推理结果的第一个First()是取第一张图片的结果// 之前定义的输出只有classLabel,所以第二个First()就是分类的名字label1.Text = model.Infer(inputImages).First().First();
}

注意,这里的数据转换一定要按照前面查看的模型的信息来转换,图片大小需要长宽都是227像素,并且要依次放置所有的蓝色分量、所有的绿色分量、所有的红色分量,如果顺序不正确,不能达到最佳的推理结果。

测试

编译运行,然后在网上找一张熊的图片,把地址填到输入框内,然后点击识别按钮,就可以看到识别的结果了。注意,这个URL应该是图片的URL,而不是包含该图片的网页的URL。

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

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

相关文章

双向数据绑定详细解析(超详细)

文章目录 一、什么是双向绑定二、双向绑定的原理是什么理解ViewModel 三、实现双向绑定实现编译Compile依赖收集 参考文献 一、什么是双向绑定 我们先从单向绑定切入单向绑定非常简单&#xff0c;就是把Model绑定到View&#xff0c;当我们用JavaScript代码更新Model时&#xf…

QML —— 使用Qt虚拟键盘示例(附完整源码)

示例效果 使用"虚拟键盘"注意 &#xff08;例子的Qt版本:5.12.4&#xff09; 注意一&#xff1a;      /* 必须在main.cpp开始处加入如下代码&#xff0c;否则无法使用"虚拟键盘" */      qputenv(“QT_IM_MODULE”,QByteArray(“qtvirtualkeybo…

苹果MacOS12系统 Monterey最新正式版下载 MacOS12系统镜像包

macOS 12 Monterey是苹果公司最新发布的操作系统&#xff0c;为Mac用户带来了更强大、更智能的功能和体验。 这个版本引入了许多令人兴奋的新特性&#xff0c;其中包括革命性的Universal Control功能&#xff0c;让你可以无缝地在Mac和iPad之间进行操作。只需将iPad放在Mac附近…

OpenCV的安装和vscode的配置

在图像处理领域&#xff0c;OpenCV的使用是必不可少的&#xff0c;这里介绍一下OpenCV的安装及其在vscode中的配置 1.OpenCV的安装 &#xff08;1&#xff09;安装依赖 sudo apt-get install build-essentialsudo apt-get install cmake git libgtk2.0-dev pkg-config libavc…

GEE——土地利用分类种两个矢量集合中不同列进行相减的方式(利用join进行连接处理)

问题: 我有两个具有相同 ID 的特征集,我想从第二个特征集中减去第一个特征集的表格单元格。 我使用了这个函数,但它计算的是表 1 中第一个元素与表 2 中其他元素的减法。 我想逐个单元格计算减法。第一个表格中 id 为 1 的单元格减去第二个表格中 id 为 1 的单元格,2x2、…

主线程退出后子线程是否还会正常运行?

问题&#xff1a; 父子线程的关系 今天突然有感而发&#xff0c; 想要来探讨一下主线程和子线程之间的关系。 例一&#xff1a;子线程执行时间较父线程慢 public class ThreadTest {public static void main(String[] args) {// 测试主线程 和 子线程Thread sonThread new …

Python 教程 01:Python 简介及发展历史

ℹ️说明&#xff1a;关于本教程的一些约定 ① 教程后有&#xff08;选读&#xff09;的表示此教程为扩展内容&#xff0c;选读&#xff1b; ② 教程中涉及到的代码片段有时候并非代码块&#xff0c;而是图片&#xff0c;这是防止初学者直接复制代码粘贴的行为&#xff0c;想必…

应用OpenCV绘制箭头

绘制箭头函数 方法&#xff1a;函数cv2.arrowedLine( ) 语法格式&#xff1a;cv2.arrowedLine(img, pt1, pt2, color[, thickness[, line_type[, shift[, tipLength]]]]) 参数说明&#xff1a; img&#xff1a;要画的直线所在的图像&#xff0c;也称为画布。。 pt1&#x…

【CSS】文字描边的三种实现方式

目录 1. 可行的几种方式1.1. text-shadow 描边代码优缺点 1.2. text-stroke 描边实现优缺点 1.3. svg 描边实现优缺点 总结 1. 可行的几种方式 text-shadow–webkit-text-strokesvg 1.1. text-shadow 描边 MDN text-shadow 代码 <div class"text stroke">…

Ubuntu软件和vmware下载

https://cn.ubuntu.com/download/desktop VMware 中国 - 交付面向企业的数字化基础 | CN

HttpRunner自动化测试工具之获取响应数据extract提取值到变量

获取响应数据 extract: 提取 注&#xff1a;extract 应与request保持同一层级 1、响应行&#xff0c;响应头&#xff1b;通过 extract 提取响应的数据并存储到变量中&#xff0c;如下图&#xff1a; 注&#xff1a;变量名的前面要有 - # 获取响应数据: 响应行&#xff08;…

【比赛专题】江苏省信息安全管理与评估 理论题样题题库整理

GZ032 信息安全管理与评估赛题第1套 一、 单选题 &#xff08;每题 2 分&#xff0c;共 35 题&#xff0c;共 70 分&#xff09; 1、《中华人民共和国数据安全法》已由中华人民共和国第十三届全国人民代 表大会常务委员会第二十九次会议通过&#xff0c;现予公布&#xff0c;自…

蓝桥杯基础知识1 字母大小写转换

蓝桥杯基础知识1 字母大小写转换 isalpha()判断一个字符是否为字母。 isalnum()判断一个字符是否为十进制数字字符或者字母&#xff0c;是否属于a~ z或A~ Z或0~9。 isdigit() 判断一个字符是否是十进制数字字符。十进制数字是&#xff1a;0 1 2 3 4 5 6 7 8 9 isalnum()和isdig…

【python】合并具有相同数字前缀的 CSV 文件

一、问题 有一个文件目录&#xff0c;目录下有类似下列文件名&#xff1a;1_a.csv、1_b.csv、1_c.csv、2_a.csv、2_b.csv、2_c.csv......即下划线前面数字相同的不同csv文件有几个&#xff0c;他们的行数相同&#xff0c;列名不同。 想把这个目录下&#xff0c;数字相同的几个…

YOLOv5改进 | 损失篇 | VarifocalLoss密集检测专用损失函数 (VFLoss,论文一比一复现)

一、本文介绍 本文给大家带来的是损失函数改进VFLoss损失函数,VFL是一种为密集目标检测器训练预测IoU-aware Classification Scores(IACS)的损失函数,我经过官方的版本将其集成在我们的YOLOv8的损失函数使用上,其中有很多使用的小细节(否则按照官方的版本使用根本拟合不了…

讨好自己的五大法宝,让生活更精彩

在这个繁忙的世界里&#xff0c;让生活更精彩并不难&#xff0c;关键是你愿不愿意给自己一点小惊喜。让我们一起探讨一下&#xff0c;如何用五大小法宝&#xff0c;讨好自己&#xff0c;让生活更加美好。 1. 每周安排“自己时间” 在繁忙的工作和学习之余&#xff0c;留出每周…

echart图表

首先我们要知道ECharts是什么,它是怎么用的&#xff1f; ECharts是一个使用JavaScript实现的开源可视化库&#xff0c;它涵盖各行业图表&#xff0c;满足各种需求。它提供了丰富的图表类型和交互能力&#xff0c;使用户能够通过国简单的配置生成各种各样的图表&#xff0c;包括…

使用opencv做双目测距(相机标定+立体匹配+测距)

最近在做双目测距&#xff0c;觉得有必要记录点东西&#xff0c;所以我的第一篇博客就这么诞生啦~ 双目测距属于立体视觉这一块&#xff0c;我觉得应该有很多人踩过这个坑了&#xff0c;但网上的资料依旧是云里雾里的&#xff0c;要么是理论讲一大堆&#xff0c;最后发现还不知…

钡铼分布式IO在玻璃制造中的实时数据采集与监控应用介绍

导读 玻璃行业多年来一直广泛使用 PLC 来帮助管理生产过程所需的精确材料比例&#xff0c;完全依赖其PLC进行数据采集与控制&#xff0c;并且大量依靠人工来操作&#xff0c;所以这些高成本推动了对成本较低的替代方案的需求。 场景描述 某玻璃厂生产的玻璃生产包括配料段、熔…

Debezium发布历史49

原文地址&#xff1a; https://debezium.io/blog/2019/02/19/reliable-microservices-data-exchange-with-the-outbox-pattern/ 欢迎关注留言&#xff0c;我是收集整理小能手&#xff0c;工具翻译&#xff0c;仅供参考&#xff0c;笔芯笔芯. 使用发件箱模式进行可靠的微服务数…