当前位置: 首页 > article >正文

C# OnnxRuntime 部署 DDColor

说明地址https://github.com/piddnad/DDColor效果模型信息Model Properties ------------------------- --------------------------------------------------------------- Inputs ------------------------- nameinput tensorFloat[1, 3, 256, 256] --------------------------------------------------------------- Outputs ------------------------- nameoutput tensorFloat[1, 2, 256, 256] ---------------------------------------------------------------项目代码using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; using OpenCvSharp; using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.Linq; using System.Windows.Forms; using Size OpenCvSharp.Size; namespace Onnx_Demo { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private readonly string fileFilter 图像文件|*.bmp;*.jpg;*.jpeg;*.tiff;*.png; private string imagePath ; private string modelPath; private Mat originalImage; private Mat resultImage; private SessionOptions sessionOptions; private InferenceSession onnxSession; private Tensorfloat inputTensor; private ListNamedOnnxValue inputContainer; private IDisposableReadOnlyCollectionDisposableNamedOnnxValue inferenceResult; private DisposableNamedOnnxValue[] resultOnnxValues; private Tensorfloat outputTensor; private const int ModelInputSize 256; // 模型固定输入尺寸 private void Form1_Load(object sender, EventArgs e) { modelPath model/ddcolor_paper_tiny.onnx; sessionOptions new SessionOptions(); sessionOptions.LogSeverityLevel OrtLoggingLevel.ORT_LOGGING_LEVEL_INFO; sessionOptions.AppendExecutionProvider_CPU(0); // 如需 GPUsessionOptions.AppendExecutionProvider_CUDA(0); onnxSession new InferenceSession(modelPath, sessionOptions); inputContainer new ListNamedOnnxValue(); string testImg test_img/Einstein, Rejection, and Crafting a Future.jpeg; if (System.IO.File.Exists(testImg)) { imagePath testImg; pictureBox1.Image new Bitmap(imagePath); originalImage new Mat(imagePath); } } private void button1_Click(object sender, EventArgs e) { OpenFileDialog ofd new OpenFileDialog(); ofd.Filter fileFilter; if (ofd.ShowDialog() ! DialogResult.OK) return; imagePath ofd.FileName; pictureBox1.Image?.Dispose(); pictureBox1.Image new Bitmap(imagePath); originalImage new Mat(imagePath); pictureBox2.Image null; textBox1.Text ; } private void button2_Click(object sender, EventArgs e) { if (string.IsNullOrEmpty(imagePath) || originalImage null) { MessageBox.Show(请先选择图片, 提示, MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } button2.Enabled false; pictureBox2.Image null; textBox1.Text ; Application.DoEvents(); try { int origH originalImage.Height; int origW originalImage.Width; // 1. 预处理 // 1.1 BGR - RGB归一化到 [0,1] 浮点 Mat rgb new Mat(); Cv2.CvtColor(originalImage, rgb, ColorConversionCodes.BGR2RGB); rgb.ConvertTo(rgb, MatType.CV_32FC3, 1.0 / 255.0); // 1.2 RGB - LAB提取 L 通道范围 0100 Mat lab new Mat(); Cv2.CvtColor(rgb, lab, ColorConversionCodes.RGB2Lab); Mat[] labChannels Cv2.Split(lab); Mat L labChannels[0]; // L 通道float范围 0100 Mat originalL L.Clone(); // 保存原始 L 用于最终合并 // 1.3 构造模型输入灰度 RGB 图通过 Lab - RGB 转换与 Python 代码一致 // 调整 L 到模型输入尺寸 256x256 Mat resizedL new Mat(); Cv2.Resize(L, resizedL, new Size(ModelInputSize, ModelInputSize), 0, 0, InterpolationFlags.Linear); // 创建三通道 Lab 图像LresizedL, a0, b0 Mat grayLab new Mat(); Mat[] grayLabChannels new Mat[3]; grayLabChannels[0] resizedL; grayLabChannels[1] Mat.Zeros(resizedL.Size(), MatType.CV_32FC1); grayLabChannels[2] Mat.Zeros(resizedL.Size(), MatType.CV_32FC1); Cv2.Merge(grayLabChannels, grayLab); // Lab - RGB得到灰度 RGB 图像范围 01 Mat grayRgb new Mat(); Cv2.CvtColor(grayLab, grayRgb, ColorConversionCodes.Lab2RGB); // 1.4 转换为 CHW 格式的 float 数组 int height grayRgb.Height; int width grayRgb.Width; float[] inputData new float[3 * height * width]; Mat[] rgbChannels Cv2.Split(grayRgb); // 顺序: R, G, B int index 0; for (int c 0; c 3; c) { float[] channelData new float[height * width]; System.Runtime.InteropServices.Marshal.Copy(rgbChannels[c].Data, channelData, 0, height * width); foreach (float val in channelData) inputData[index] val; } var inputTensor new DenseTensorfloat(inputData, new[] { 1, 3, height, width }); // 2. 推理 var inputs new ListNamedOnnxValue { NamedOnnxValue.CreateFromTensor(input, inputTensor) }; DateTime t1 DateTime.Now; using (var results onnxSession.Run(inputs)) { DateTime t2 DateTime.Now; var output results.First(item item.Name output).AsTensorfloat(); float[] outputData output.ToArray(); // shape: [1, 2, 256, 256] float minVal outputData.Min(); float maxVal outputData.Max(); // 3. 后处理 int outH ModelInputSize; int outW ModelInputSize; // 3.1 将输出 ab 通道转换为双通道 Mat (HWC, float) Mat abMat new Mat(outH, outW, MatType.CV_32FC2); int idx 0; for (int y 0; y outH; y) { for (int x 0; x outW; x) { Vec2f ab; ab.Item0 outputData[idx]; // a 通道 ab.Item1 outputData[idx outH * outW]; // b 通道 abMat.Set(y, x, ab); idx; } } // 3.2 将 ab 双通道图放大到原始图像尺寸双线性插值 Mat resizedAb new Mat(); Cv2.Resize(abMat, resizedAb, new Size(origW, origH), 0, 0, InterpolationFlags.Linear); // 3.3 合并原始 L 与放大后的 ab 得到 LAB 图像 Mat[] labResultChannels new Mat[3]; labResultChannels[0] originalL; // L (0100) Mat[] abChannels Cv2.Split(resizedAb); // abChannels[0] a, abChannels[1] b labResultChannels[1] abChannels[0]; labResultChannels[2] abChannels[1]; Mat labResult new Mat(); Cv2.Merge(labResultChannels, labResult); // 3.4 LAB - RGB - BGR用于显示/保存 Mat rgbResult new Mat(); Cv2.CvtColor(labResult, rgbResult, ColorConversionCodes.Lab2RGB); Mat bgrResult new Mat(); Cv2.CvtColor(rgbResult, bgrResult, ColorConversionCodes.RGB2BGR); // 3.5 将像素值从 [0,1] 转到 [0,255] 并转为 8UC3 bgrResult.ConvertTo(bgrResult, MatType.CV_8UC3, 255.0); resultImage bgrResult.Clone(); pictureBox2.Image new Bitmap(resultImage.ToMemoryStream()); textBox1.Text $推理耗时: {(t2 - t1).TotalMilliseconds:F2} ms; // 释放资源 abMat.Dispose(); resizedAb.Dispose(); foreach (var m in abChannels) m.Dispose(); labResult.Dispose(); rgbResult.Dispose(); } // 释放资源 rgb.Dispose(); lab.Dispose(); L.Dispose(); resizedL.Dispose(); grayLab.Dispose(); grayRgb.Dispose(); foreach (var m in rgbChannels) m.Dispose(); foreach (var m in labChannels) m.Dispose(); foreach (var m in grayLabChannels) m.Dispose(); } catch (Exception ex) { MessageBox.Show($推理失败: {ex.Message}, 错误, MessageBoxButtons.OK, MessageBoxIcon.Error); textBox1.Text 推理出错; } finally { button2.Enabled true; } } private void button3_Click(object sender, EventArgs e) { if (resultImage null || resultImage.Empty()) { MessageBox.Show(请先进行推理, 提示, MessageBoxButtons.OK, MessageBoxIcon.Information); return; } SaveFileDialog sfd new SaveFileDialog(); sfd.Title 保存图像; sfd.Filter PNG图片 (*.png)|*.png|JPEG图片 (*.jpg)|*.jpg|BMP图片 (*.bmp)|*.bmp; sfd.FilterIndex 1; if (sfd.ShowDialog() DialogResult.OK) { string ext System.IO.Path.GetExtension(sfd.FileName).ToLower(); ImageFormat format ImageFormat.Png; if (ext .jpg || ext .jpeg) format ImageFormat.Jpeg; elseif (ext .bmp) format ImageFormat.Bmp; using (var stream resultImage.ToMemoryStream()) using (var bitmap new Bitmap(stream)) { bitmap.Save(sfd.FileName, format); } MessageBox.Show($保存成功\n位置: {sfd.FileName}, 完成, MessageBoxButtons.OK, MessageBoxIcon.Information); } } private void pictureBox1_DoubleClick(object sender, EventArgs e) { ShowImageInNormalWindow(pictureBox1.Image); } private void pictureBox2_DoubleClick(object sender, EventArgs e) { ShowImageInNormalWindow(pictureBox2.Image); } private void ShowImageInNormalWindow(Image img) { if (img null) return; Form frm new Form { Width img.Width 20, Height img.Height 40, StartPosition FormStartPosition.CenterScreen, Text 查看大图 }; PictureBox pb new PictureBox { Image img, Dock DockStyle.Fill, SizeMode PictureBoxSizeMode.Zoom }; frm.Controls.Add(pb); frm.ShowDialog(); } } }

相关文章:

C# OnnxRuntime 部署 DDColor

说明地址:https://github.com/piddnad/DDColor效果模型信息Model Properties ------------------------- ---------------------------------------------------------------Inputs ------------------------- name:input tensor:Float[1, 3,…...

告别Source Insight卡顿!用Vim + Ctags + Cscope打造Linux下丝滑的C/C++代码阅读环境

打造Linux下极致流畅的C/C代码阅读环境:Vim Ctags Cscope实战指南 第一次在Linux服务器上打开一个大型C项目时,我盯着终端里密密麻麻的代码手足无措。图形化IDE在远程桌面上的卡顿让我几乎无法工作,每次跳转定义都要等待数秒,开…...

基于Kotti-py312这个项目,帮我写一个AI 交流网站。先帮我规划一下!我的诉求是能实现AI资源的互助,大家互相帮着找点子,一起落地实践!

基于Kotti-py312这个项目,帮我写一个AI 交流网站。先帮我规划一下! 我的诉求是能实现AI资源的互助,大家互相帮着找点子,一起落地实践!Kotti-py312这个项目代码在:G:\dumatework核心理念:AI 资源…...

Sunshine游戏串流终极指南:15分钟打造你的跨设备游戏天堂

Sunshine游戏串流终极指南:15分钟打造你的跨设备游戏天堂 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine Sunshine是一款开源的自托管游戏串流服务器,专为M…...

g4f提供的模型调用:python JavaScript和curl

g4f提供模型的使用,例子页面:G4F - Providers and Models 可以这样: python from g4f.client import Clientclient Client() response client.chat.completions.create(model"",messages[{"role": "user"…...

告别Keil:在Windows上构建VSCode+GCC+OpenOCD一体化ARM开发环境

1. 为什么选择VSCodeGCCOpenOCD替代Keil? 作为一名在嵌入式领域摸爬滚打多年的开发者,我深知传统IDE(如Keil)给开发者带来的种种困扰。高昂的授权费用、臃肿的安装包、缓慢的编译速度,以及那仿佛停留在上个世纪的代码编…...

AI测试标准更新:2026年新规详解

从“野蛮生长”到“有标可依”的行业转折点进入2026年,人工智能技术已深度融入各行各业,从生成式内容创作到具身智能机器人,AI系统正以前所未有的速度重塑生产和生活。然而,技术狂奔的背后,是日益凸显的风险与挑战&…...

Netflix四月底推重新设计移动应用,竖版视频流能否拓展娱乐新体验?

Netflix移动应用四月底焕新,竖版视频流登场 Netflix于周四宣布,将在四月底推出重新设计的移动应用程序,其中一大亮点是包含竖版视频流。该公司在2026年第一季度致股东的财报信中提及,此次重新设计旨在更好地体现不断拓展的娱乐内容…...

告别Excel手工作坊:用Tableau Prep Builder 2024.1自动化清洗销售数据的保姆级教程

告别Excel手工作坊:用Tableau Prep Builder 2024.1自动化清洗销售数据的保姆级教程 销售数据就像一座金矿,但大多数时候我们却用勺子而不是挖掘机在开采。想象一下这样的场景:每月底,你从CRM系统导出客户订单,从财务系…...

Depix实战手记:从原理到踩坑,一次不完美的马赛克破解尝试

1. Depix初体验:当马赛克遇上逆向工程 第一次听说Depix这个项目时,我正在帮朋友处理一张被打满马赛克的图片。那画面简直就像被泼了一桶油漆,完全看不出原貌。正当我准备放弃时,突然想起在技术论坛上看到过关于Depix的讨论——这个…...

MinerU 系列教程 第八课:Office 后端 - DOCX/PPTX 原生解析

MinerU 系列教程 第八篇 本篇教程将深入 Office 后端的原生文档解析机制。前三课分别剖析了 Pipeline、VLM、Hybrid 三种针对 PDF 的解析后端,而 Office 后端走了一条完全不同的路线 —— 直接从 DOCX/PPTX 的 XML 源码中提取结构化内容,无需 OCR、无需版面检测、无需任何 AI…...

Excalidraw虚拟白板工具:如何用5分钟开启你的手绘图表创作之旅?

Excalidraw虚拟白板工具:如何用5分钟开启你的手绘图表创作之旅? 【免费下载链接】excalidraw Virtual whiteboard for sketching hand-drawn like diagrams 项目地址: https://gitcode.com/GitHub_Trending/ex/excalidraw 你是否厌倦了传统图表工…...

Omni-Vision Sanctuary 算法优化实战:提升模型推理与训练效率

Omni-Vision Sanctuary 算法优化实战:提升模型推理与训练效率 1. 引言:为什么需要算法优化 在计算机视觉领域,Omni-Vision Sanctuary模型因其强大的多任务处理能力而备受关注。但随着模型规模扩大和应用场景复杂化,算法工程师们…...

终极指南:如何用Win_ISO_Patching_Scripts快速制作集成最新补丁的Windows安装镜像

终极指南:如何用Win_ISO_Patching_Scripts快速制作集成最新补丁的Windows安装镜像 【免费下载链接】Win_ISO_Patching_Scripts Win_ISO_Patching_Scripts 项目地址: https://gitcode.com/gh_mirrors/wi/Win_ISO_Patching_Scripts 还在为手动集成Windows补丁而…...

速德瑞313/340/351nm紫外检测仪器全适配JJF 2132—2024

JJF2132—2024《荧光紫外灯人工气候老化试验装置校准规范》于2024年12月14日正式实施,核心监测波段升级为340nm、351nm、313nm,同时明确310通道和340通道监测要求。速德瑞准确响应新规,不仅推出匹配310/340nm波段的氙灯辐照计,更构…...

行业创新技术:区块链测试应用前瞻

当测试遇上区块链,质量保障的新边疆随着数字化转型的浪潮席卷全球,软件测试作为保障系统质量的关键环节,正面临着前所未有的挑战:数据真实性难以验证、跨系统协作流程追溯困难、安全审计要求日益严苛。与此同时,区块链…...

GMS基本测试命令

1. 跑签名报告申请白名单的命令:run gts -m GtsEdiHostTestCases -s run cts -m CtsCurrentApiSignatureTestCases -t android.signature.cts.api.SignatureTest#testSignature -s 【devicesID】2. 全跑CTS报告命令:run cts -s 【devicesID】3. 全跑STS…...

Claude Code 深度安装与避坑指南(小白级实操版)

如果你听说过 Claude Code,但被那些黑漆漆的命令行(Terminal)挡住了去路,这份文档就是为你准备的。我们不仅教你如何安装,更要把你可能踩到的“权限、网络、路径”大坑提前填平。 第一步:安装必备软件 1、…...

手把手教你用Verilog实现一个简易8点FFT:理解蝶形运算与旋转因子

从零实现8点FFT:Verilog硬件设计中的蝶形运算实战 在数字信号处理领域,快速傅里叶变换(FFT)堪称算法皇冠上的明珠。想象一下,当你面对一段音频波形或无线电信号时,如何快速识别其中隐藏的频率成分&#xff…...

从零开始:用DSP28335手把手实现BLDC六步换相(附完整代码与避坑指南)

从零开始:用DSP28335手把手实现BLDC六步换相(附完整代码与避坑指南) 1. 硬件准备与开发环境搭建 1.1 所需硬件清单 DSP28335开发板:推荐使用TI官方评估板或兼容开发板BLDC电机:建议选择24V/500W以内带霍尔传感器的电机…...

告别玄学调参!手把手教你用SX1262 LoRa模块实现5公里稳定通信(附完整代码)

告别玄学调参!手把手教你用SX1262 LoRa模块实现5公里稳定通信(附完整代码) 在物联网设备开发中,LoRa技术因其远距离、低功耗的特性成为许多项目的首选。但当你真正开始使用SX1262这类LoRa模块时,可能会发现实际通信距离…...

楚汉传奇---Python脚本

脚本如下#!/usr/bin/env python3 # -*- coding: utf-8 -*-""" YouTube 下载工具 (基于 yt-dlp) 支持:单个视频、播放列表、仅音频、画质选择、进度显示、错误重试等 """import yt_dlp import os import sys import argparse import s…...

AI Agent Harness Engineering 与边缘计算结合的实时控制应用

AI Agent Harness Engineering 与边缘计算结合的实时控制应用 ——以工业机器人“多材质小批量混流”自适应柔性抓取工作站为例一、引言 (Introduction) (一)钩子:从3个真实“痛点场景”看制造业的“卡脖子”焦虑 各位技术爱好者、智能制造工…...

职业院校智慧校园采购怎样才算明智?聊聊性价比与易用性的那些事

✅作者简介:合肥自友科技 📌核心产品:智慧校园平台(包括教工管理、学工管理、教务管理、考务管理、后勤管理、德育管理、资产管理、公寓管理、实习管理、就业管理、离校管理、科研平台、档案管理、学生平台等26个子平台) 。公司所有人员均有多…...

生成式AI实时通信的“隐形瓶颈”:模型Tokenizer流式切分与网络MTU错配问题(附Wireshark抓包取证全过程)

第一章:生成式AI应用实时通信方案 2026奇点智能技术大会(https://ml-summit.org) 生成式AI应用对低延迟、高并发、上下文感知的实时通信能力提出全新要求。传统REST API轮询或短连接模式难以支撑流式推理响应、多模态协同编辑、Agent间动态协商等典型场景。现代架构…...

《允许孩子做自己:从“听话”到“自主”,守护成长的独特轨迹》

允许孩子做自己,本质上是尊重他们作为独立个体的天性与权利,这对孩子的成长有着深远的意义:从成长规律来看,每个孩子都有独特的气质、兴趣和节奏——有的孩子天生敏感细腻,喜欢安静观察;有的活泼好动&#…...

bootstrap如何设置响应式导航栏的切换宽度

<p>navbar-expand-* 类决定导航栏水平展开的最小屏幕宽度&#xff0c;如 navbar-expand-md 表示 ≥768px 时展开、小于该值时折叠为汉堡菜单&#xff0c;断点由 Bootstrap 预设且不可自定义像素值。</p>如何用 navbar-expand-* 控制折叠临界点bootstrap 导航栏的“…...

STM32调试新姿势:5分钟上手SEGGER RTT Viewer,实时查看变量和日志

STM32调试新姿势&#xff1a;5分钟上手SEGGER RTT Viewer&#xff0c;实时查看变量和日志 调试嵌入式系统时&#xff0c;传统的串口打印方式往往让人又爱又恨。爱的是它简单直接&#xff0c;恨的是每次都要插拔串口线、打开多个终端窗口&#xff0c;调试效率大打折扣。如果你正…...

告别document.querySelector!在Vue3中用ref优雅操作DOM的3个实战场景

告别document.querySelector&#xff01;在Vue3中用ref优雅操作DOM的3个实战场景 在Vue3的生态中&#xff0c;模板ref早已超越了简单的DOM引用工具&#xff0c;成为连接响应式数据与命令式DOM操作的桥梁。许多开发者仍习惯性地在setup中写下document.querySelector——这就像用…...

AD7656与DSP通信时序深度解析:如何用示波器搞定数据跳变和读取为0的故障

AD7656与DSP通信时序深度解析&#xff1a;如何用示波器搞定数据跳变和读取为0的故障 在高速数据采集系统的调试现场&#xff0c;AD7656模数转换器与DSP的通信问题堪称经典案例。当示波器屏幕上出现异常波形时&#xff0c;工程师需要像侦探破案一样&#xff0c;从时序关系的蛛丝…...