跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C#AI算法

基于 ONNX Runtime 的 C# 模型封装与推理实现

介绍如何使用 C# 和 ONNX Runtime 在 Windows 窗体应用中加载并推理 ONNX 模型。内容涵盖项目搭建、界面设计、模型文件配置、NuGet 包集成、图像预处理及张量转换逻辑。通过示例代码演示了从图片加载到结果输出的完整流程,并提供了常见环境问题的排查方法,帮助开发者快速集成深度学习模型至桌面应用。

极客零度发布于 2025/2/7更新于 2026/9/1984 浏览
基于 ONNX Runtime 的 C# 模型封装与推理实现

基于 ONNX Runtime 的 C# 模型封装与推理实现

本文介绍如何在 Windows 窗体应用中集成 ONNX Runtime,加载自定义的 ONNX 模型并进行图像推理。ONNX (Open Neural Network Exchange) 是一个开放的机器学习模型格式,支持跨平台部署。通过 Microsoft 提供的 ONNX Runtime 库,开发者可以在 C# 环境中高效地执行模型推理。

环境准备

在开始之前,请确保已正确安装配置了 Visual Studio 2017 或更高版本以及 .NET Framework 开发环境。建议使用最新的稳定版 SDK。

项目创建

  1. 打开 Visual Studio,选择 文件 -> 新建 -> 项目。
  2. 选择 Windows 窗体应用 (.NET Framework) 模板。
  3. 将项目名称命名为 ClassifyBear(或其他符合命名规范的名称)。

界面设计

在解决方案资源管理器中找到 Form1.cs,双击打开界面设计器。从工具箱中向 Form 中依次拖入控件并调整布局,最终效果应包含以下元素:

  • Label 控件:位于左侧上方,内容修改为'输入要识别的图片地址:'。
  • TextBox 控件:用于输入图片 URL 或本地路径,建议拉长以方便查看。
  • Button 控件:内容修改为'识别',触发推理逻辑。
  • Label 控件:用于显示识别后的结果文本。由于默认无边框,建议调大字体以便清晰阅读。
  • PictureBox 控件:位于右侧,用于预览输入的图片。建议将 SizeMode 属性更改为 StretchImage,并将长宽设置为相同值(如 224x224),保持正方形形状,这与大多数视觉模型的输入要求一致。

添加模型文件到项目中

  1. 在解决方案资源管理器中,右键点击项目节点,选择 添加 -> 现有项。
  2. 在弹出的对话框中,将文件类型过滤器改为 所有文件 (*.*)。
  3. 导航到模型所在目录,选择 .onnx 模型文件(例如 BearModel.onnx)并添加。
  4. 关键配置:选中刚添加的模型文件,在属性面板中将 生成操作 属性改为 内容,将 复制到输出目录 属性改为 如果较新则复制。这确保了编译时模型文件会被复制到程序运行目录,避免运行时找不到文件。

集成 ONNX Runtime 库

微软开源的 ONNX Runtime 提供了 NuGet 包,可方便地集成到 Visual Studio 项目中。

  1. 在解决方案资源管理器中,右键点击 引用,选择 管理 NuGet 程序包。
  2. 切换到 浏览 选项卡,搜索 Microsoft.ML.OnnxRuntime。
  3. 找到该包并点击安装。当前推荐版本通常为最新稳定版(示例中使用 0.4.0 作为参考,实际使用时请检查最新版本)。
  4. 架构设置:NuGet 发布的库通常支持 x64 及 x86 架构。建议使用 x64 以获得更好的性能。
    • 右键点击解决方案,选择 配置管理器。
    • 将活动解决方案平台切换为 x64。如果没有,在下拉框中选择 新建,按提示创建 x64 平台。

处理输入并加载模型进行推理

在 上右键,选择 ,打开代码编辑窗口。

Form1.cs
查看代码

1. 定义常量与成员变量

首先定义图片尺寸常量,这取决于模型训练时的输入规格。本示例假设模型输入为 224x224 像素。

// 使用 Netron 等工具查看模型,确认模型的输入应为 224*224 大小的图片
private const int imageSize = 224;

2. 按钮点击事件处理

双击界面上的'识别'按钮,自动生成 button1_Click 方法。在此方法中编写核心逻辑。

重置界面状态

每次点击识别前,先清除上一次的结果和预览图。

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

尝试从 TextBox 中输入的地址加载图片。需处理可能的异常(如网络错误、无效路径)。

bool isSuccess = false;
try
{
    // 注意:Load 方法支持 URL 和本地路径,但需确保权限和网络连通性
    pictureBox1.Load(textBox1.Text);
    isSuccess = true;
}
catch (Exception ex)
{
    MessageBox.Show($"读取图片时出现错误:{ex.Message}");
    throw; // 或者根据需求选择是否继续
}
图像预处理与张量构建

如果加载成功,需要将图片转换为模型所需的浮点型数组。注意颜色通道顺序和归一化问题。

if (isSuccess)
{
    // 图片加载成功后,从图片控件中取出指定大小的位图对象
    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);

            // 注意:不同模型对输入通道顺序要求不同
            // 常见情况是 BGR 或 RGB,此处根据模型文档调整
            // 示例中假设需要依次放置蓝色分量、绿色分量、红色分量
            imageArray[y * imageSize + x] = color.B;
            imageArray[y * imageSize + x + 1 * imageSize * imageSize] = color.G;
            imageArray[y * imageSize + x + 2 * imageSize * imageSize] = color.R;
        }
    }

    // 设置要加载的模型的路径,根据实际部署环境调整
    string modelPath = AppDomain.CurrentDomain.BaseDirectory + "BearModel.onnx";

    using (var session = new InferenceSession(modelPath))
    {
        var container = new List<NamedOnnxValue>();

        // 输入数据维度通常为 [Batch_Size, Channels, Height, Width]
        // 第一维 None 表示可以传入多张图片进行推理,这里只使用一张图片
        var shape = new int[] { 1, 3, imageSize, imageSize };
        var tensor = new DenseTensor<float>(imageArray, shape);

        // 添加输入,输入名称需与模型定义中的输入节点名称一致
        // 对于 MNIST 类模型,输入名称通常是 'data' 或 'input'
        container.Add(NamedOnnxValue.CreateFromTensor<float>("data", tensor));

        // 执行推理
        var results = session.Run(container);

        // 解析输出结果
        // 输出可能包含多个节点,如 classLabel 和 loss,这里只关心分类标签
        var label = results.FirstOrDefault(item => item.Name == "classLabel")?
            .AsTensor<string>()?
            .FirstOrDefault();

        // 显示在控件中
        if (!string.IsNullOrEmpty(label))
        {
            label1.Text = $"识别结果:{label}";
        }
        else
        {
            label1.Text = "未获取到有效结果";
        }
    }
}

重要提示:数据转换必须严格遵循模型信息。图片大小需匹配(如 224x224),且颜色通道顺序(BGR/RGB)和数值范围(0-255 或 0-1)需与训练时一致。如果顺序或归一化不正确,将无法达到最佳推理效果。

常见问题排查

1. 缺少 DLL 文件

如果运行时遇到找不到 onnxruntime.dll 的错误,可能是编译时相关库没有拷贝到运行目录下。

  • 解决方法:清理解决方案,然后重新编译。
  • 手动修复:也可以手动到 packages\Microsoft.ML.OnnxRuntime.版本号\runtimes\win-x64\native 下将 onnxruntime.dll 拷贝到程序运行目录(即 bin\Debug 或 bin\Release)。

2. 架构不匹配

确保项目目标架构(x64/x86)与安装的 ONNX Runtime 库支持的架构一致。如果混用可能导致加载失败。

3. 模型输入名称错误

如果推理报错提示输入名称不存在,请使用 Netron 等工具查看 .onnx 文件的输入节点名称,并更新代码中的 CreateFromTensor 参数。

总结

通过上述步骤,我们成功在 C# WinForms 应用中集成了 ONNX Runtime,实现了图像的加载、预处理及模型推理。此方案适用于需要在桌面端部署轻量级 AI 模型的场景。在实际生产中,建议增加异步处理以避免 UI 阻塞,并根据具体模型需求调整图像预处理逻辑(如归一化、均值减法等)。

目录

  1. 基于 ONNX Runtime 的 C# 模型封装与推理实现
  2. 环境准备
  3. 项目创建
  4. 界面设计
  5. 添加模型文件到项目中
  6. 集成 ONNX Runtime 库
  7. 处理输入并加载模型进行推理
  8. 1. 定义常量与成员变量
  9. 2. 按钮点击事件处理
  10. 重置界面状态
  11. 加载图片
  12. 图像预处理与张量构建
  13. 常见问题排查
  14. 1. 缺少 DLL 文件
  15. 2. 架构不匹配
  16. 3. 模型输入名称错误
  17. 总结

更多推荐文章

查看全部
  • LLM 存储优化实战:解决大量 QA 与长对话记忆问题
  • Docker 多容器编排:Compose 实战教程
  • 微信 ClawBot 插件接入个人微信及 Windows 安装踩坑指南
  • JDK21 下载与安装指南
  • GitHub Copilot 接入 Figma MCP 还原设计稿生成前端代码
  • VSCode 本地运行 DeepSeek 模型配置指南
  • 基于 Java SSM 的咖啡奶茶点餐推荐系统
  • Agent 智能体开发框架对比:主流方案选型指南
  • NestJS 接口响应 Message 编写规范与 API 提示标准化
  • AI 业务架构搭建方法与关键实践
  • DeepSeek 大模型在云平台的优化实践与应用落地
  • Java 利用 Spire.XLS 精确控制 Excel 打印页边距
  • Rust 异步 Web 框架 Axum 的深入原理与高级用法
  • 蚂蚁开源 Ring-lite:2.75B 激活参数轻量级推理模型
  • AI 时代细胞生物学最新进展:从图像分析到虚拟细胞
  • 大模型应用:如何指导 Agent 像人一样思考及思维链范式解析
  • Python 实现中秋月相计算与月球数据可视化
  • 如何深入系统地学习 Python
  • SWE-agent:基于 GPT-4 的开源 AI 程序员系统解析与实战指南
  • C++ 智能指针:示例、原理与适用场景详解

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online