news 2026/9/7 6:02:56

别再被忽悠了!C# 搭配 YOLO 做工业视觉,门槛真的没你想的那么高

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
别再被忽悠了!C# 搭配 YOLO 做工业视觉,门槛真的没你想的那么高

历经11年从事工业上位机开发工作, 我目睹许许多多工程师于AI视觉这条道路上出现走错路的状况。

网上百分之九十的YOLO教程, 都是关于生态方面的, 而工业现场百分之九十的上位机, 都是基于C# /WPF进行开发的, 于是便出现了一个极其尴尬的状况, 所做的原型在实验室运行得挺不错, 然而一到现场, 要集成到现有的系统时, 就出现了各种各样的问题, 比如打包困难、部署遇到难题、维护存在难点、与PLC通信颇具艰难, 终归项目在“最后一公里”受阻, 活生生地被拖垮了。

不少人由此衍生出了一种误解, 即: 运用C#去开展YOLO工业视觉, 其门槛相当高, 这要求具备深厚的AI功底以及C++底层能力。

就在今天, 我会凭借自己诸多落地项目所积累的实战经验来告知你, 当下的C#与YOLO相结合, 其门槛着实并非很高。身为一名普通的C#上位机工程师, 只要掌握基本的面向对象编程, 在一周之内, 便能够制作出一个可以在产线上运行的工业级视觉检测系统。

一、先搞清楚:为什么工业界最终选择了 C#+YOLO?

在决定技术路线之前, 我们得先明确工业场景的核心诉求, 核心诉求是稳定要优先, 部署需简单, 维护成本要低, 还要与现有系统无缝地集成。

我尝试过市面上差不多所有的技术组合的情况, 踩过数不清的坑, 最终在几十个历经验证的项目当中, C#上位机加上/11, 再加上ONNX, 是当下综合总体表现最为良好的方案。

表格

很多人会说:" 做 YOLO 不是更简单吗?"

确实, 写个demo是简单的, 然而工业现场并非实验室。你去试着把程序打包成一个单文件exe , 接着部署到没有网络、也没有环境的工控机上。你再试着让一个只会C#的现场维护工程师去调试代码。你又去试试让程序连续跑7×24小时而不出现内存泄漏。

这些问题,在 C# 生态里根本就不是问题。

二、C#+YOLO 工业视觉系统架构

许多人一旦听闻AI视觉便会觉得繁杂, 实际上将整个系统进行拆解后极为简单, 存在五个核心模块。

第 1 层为图像采集层, 这一层要对接工业相机, 像海康、大华、巴斯勒等品牌的相机, 由其来负责图像的硬触发或者软触发采集, 紧接着是预处理层,该层在采集好图像后, 要开展缩放、归一化、ROI 裁剪等操作, 随后进入推理层, 推理层需加载 YOLO 模型, 以此执行推理计算, 并输出检测结果, 之后是业务处理层, 业务处理层要针对检测结果做解析、判断以及统计, 进而生成控制信号, 最后是输出层, 输出层要用与 PLC 通信的方式来控制剔除机构, 同时还要生成质检报表, 并且把数据上传到 MES 系统。

你瞧, 是不是除了推理层属于新的事物, 其他的那四个模块, 不就是在我们平常做上位机这件事的时候, 天天都要去写的内容呀?

三、5 分钟快速上手:写出你的第一个 YOLO 检测程序

我能够十分肯定地担保, 只要你具备会去运用的能力, 在5分钟的限定时间之内, 就将可以成功运行通过第一个YOLO检测程序。

步骤 1:创建项目并安装依赖

开启, 处于二零二二年这个时段, 8 的控制台类型项目(假设是上位机的情形, 构建出WPF或者别的相关项目), 紧接着借助NuGet这一方式来实施 , 三个包:

Install-Package Microsoft.ML.OnnxRuntime.Gpu Install-Package OpenCvSharp4 Install-Package OpenCvSharp4.runtime.win

就是这三个包, 不存在其他任何依赖, 不需要进行安装,不需要安装CUDA(当然要是有GPU那就更好了), 不需要任何复杂的环境配置。

步骤 2:准备 YOLO 模型

前往YOLO的官方网站, 获取下载一个预先训练好的模型, 接着把它导出成为ONNX格式。

# 这一步只需要在你的开发电脑上做一次 from ultralytics import YOLO model = YOLO("yolo11s.pt") model.export(format="onnx", opset=12, dynamic=False)

有一个情况是, 当导出操作达成完成状态之后 , 你能够获得一个.onnx格式的文件 , 然后要把这个文件进行复制 , 复制的目的地是你的C#项目的输出目录的下面。

步骤 3:编写检测代码

核心代码不到 50 行:

using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; using OpenCvSharp; // 初始化推理会话 var options = new SessionOptions(); options.GraphOptimizationLevel = GraphOptimizationLevel.ORT_ENABLE_ALL; // 自动选择GPU或CPU try { options.AppendExecutionProvider_Cuda(0); Console.WriteLine("使用GPU加速"); } catch { options.AppendExecutionProvider_CPU(); Console.WriteLine("使用CPU推理"); } using var session = new InferenceSession("yolo11s.onnx", options); // 读取图片 using var img = Cv2.ImRead("test.jpg"); var resized = img.Resize(new Size(640, 640)); // 图像预处理 var input = new DenseTensor(new[] { 1, 3, 640, 640 }); for (int y = 0; y < 640; y++) { for (int x = 0; x < 640; x++) { input[0, 0, y, x] = resized.At(y, x)[2] / 255f; input[0, 1, y, x] = resized.At(y, x)[1] / 255f; input[0, 2, y, x] = resized.At(y, x)[0] / 255f; } } // 执行推理 var inputs = new List { NamedOnnxValue.CreateFromTensor("images", input) }; using var outputs = session.Run(inputs); var output = outputs.First().AsTensor(); // 解析结果 var results = new List(); for (int i = 0; i < output.Dimensions[1]; i++) { float confidence = output[0, i, 4]; if (confidence < 0.5f) continue; float x = output[0, i, 0]; float y = output[0, i, 1]; float w = output[0, i, 2]; float h = output[0, i, 3]; int classId = 0; float maxClassConf = 0; for (int c = 0; c < output.Dimensions[2] - 5; c++) { float classConf = output[0, i, 5 + c]; if (classConf > maxClassConf) { maxClassConf = classConf; classId = c; } } results.Add(new Detection { ClassId = classId, Confidence = confidence * maxClassConf, X1 = (x - w / 2) * img.Width / 640, Y1 = (y - h / 2) * img.Height / 640, X2 = (x + w / 2) * img.Width / 640, Y2 = (y + h / 2) * img.Height / 640 }); } // 绘制结果 foreach (var det in results) { Cv2.Rectangle(img, new Point((int)det.X1, (int)det.Y1), new Point((int)det.X2, (int)det.Y2), Scalar.Red, 2); Cv2.PutText(img, #34;{classNames[det.ClassId]} {det.Confidence:F2}", new Point((int)det.X1, (int)det.Y1 - 10), HersheyFonts.HersheySimplex, 0.5, Scalar.Red, 2); } Cv2.ImShow("Result", img); Cv2.WaitKey(0); class Detection { public int ClassId { get; set; } public float Confidence { get; set; } public float X1 { get; set; } public float Y1 { get; set; } public float X2 { get; set; } public float Y2 { get; set; } } string[] classNames = new string[] { "person", "bicycle", "car", /* ... 其他类别 */ };

运行一下,你就会看到检测结果了。是不是比你想象的简单得多?

四、工业级优化:让你的系统稳定跑 7×24 小时

上面呈现的代码仅仅是一个演示示例, 若要应用于工业现场环境, 那么还得去开展一些至关重要的优化工作。而这些优化内容是我历经无数次挫折与失败后总结归纳出来的, 能够直接照搬使用。

1. 性能进行优化, 要使得推理速度能够飞速提升起来, 稳定性予以优化, 要杜绝内存出现泄漏以及崩溃情况, 工业场景开展适配, 要解决现场实际存在的问题, 真实工业案例展示, 我运用C#加上YOLO在一周时间内就搞定的项目。

我去年为天津的一家汽车零部件工厂制作了一个座椅滑轨缺陷检测系统, 此检测系统是运用C#进行开发的, 整个从开发直至验收的过程仅仅耗费了一周时间。

生产线上的需求是, 要对座椅滑轨表面进行检测, 检测的内容包括划痕、凹坑以及缺料这三种缺陷, 生产线运行的速度为每秒1.2米, 同时还要求误检的比率要小于0.1%, 并且漏检的比率等于0。

系统架构:

最终效果:

要是针对这个项目采用 + 来操作, 单单是授权方面的费用就得达到好几万块钱, 并且开发周期往少里说也得有一个月。然而要是运用 C#+YOLO 的方式, 不但授权是免费的, 而且开发速度相较于之前还加快了好几倍呢。

六、那些年之内, 我曾经踩过的坑, 你不用再去踩了, 其中坑1是, 推理所得到的结果, 跟端并不一致。

原因:图像预处理方式不同(归一化、通道顺序、数据类型)。

解决办法: 做到严格依规与C#的预处理代码对齐, 进行逐像素的对比。我曾在将BGR转换为RGB之际弄反了, 致使检测精度降低了30%, 查找了足足两天时间才把问题找出来。

坑 2:内存泄漏,程序跑几个小时就崩溃

Mat对象没能予以及时地释放, ONNX会话未能进行正确地销毁, 这便是原因。

办法是: 全部并非托管的资源达成接口, 运用using语句。要记住: 于C#之中, 只要是跟并非托管代码产生交互作用的对象, 均需要手动去解除占用。

坑 3:工业现场光照变化大,检测精度下降

原因:训练数据没有覆盖所有光照条件。

解决办法是, 去采集处于各异光照状况下的图像, 以此来增添数据增强。于相机一端设置自动曝光以及自动增益, 又或者采用环形光源还有背光光源。

坑 4:产线速度快,剔除位置不准确

原因:信号传输延迟、气缸响应时间不一致。

解决办法是, 精确地去计算延迟的时间, 运用编码器实现同步, 于PLC那个地方达成精准的延时, 而非在上位机那边进行延时操作。

七、最后说几句真心话

好多人认为AI视觉极为高大上, 有着颇高的门槛。实则并非如此。当下的工具链已然相当成熟, YOLO将模型训练以及推理的复杂度降至最低, ONNX把跨平台部署的问题给解决掉了, C#把工业上位机开发的效率提升至最高。

身为一名平常的 C# 上位机工程师, 无需晓得啥神经网络原理, 不必会编写 CUDA 内核, 只要会去调用 API, 会对图像予以处理, 会跟 PLC 展开通信, 便能够打造出工业级的视觉检测系统。

当然了, 我并非是在讲不好, 它极为适合用于开展算法研究以及进行原型验证, 然而在工业落地此种场景之下, C#加上YOLO绝对是当下最为出色的选择。

假设你正从事工业自动化方面的工作, 有着为自身设备增添AI视觉能力的想法, 那么就不要再迟疑了, 去尝试一下C#+YOLO这样一套方案吧。请相信我, 日后你会回过头来对我心怀感激的。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/7 6:02:20

基于虚幻引擎与AirSim的无人机作战仿真系统搭建指南

简介&#xff1a;无人机作战仿真是通过虚拟环境复现复杂战场态势、验证飞行控制与感知算法的关键技术。其核心原理是利用高保真渲染引擎与物理动力学模型&#xff0c;让无人机在虚拟场景中完成飞行、感知和任务执行&#xff0c;从而为算法验证提供接近真实的数据流。成熟方案的…

作者头像 李华
网站建设 2026/8/30 13:40:01

C盘莫名爆满?WinSxS安全清理腾出20G!C盘瘦身看这里!

&#xff08;1&#xff09;问题背景 不少朋友遇到特别诡异的C盘故障&#xff0c;没有安装大型游戏&#xff0c;微信、视频文件也都迁移到D盘&#xff0c;C盘还是直接飘红告警。点开C盘各个文件夹挨个查看&#xff0c;会发现WinSxS这个名字十分拗口的文件夹体积大得吓人&#x…

作者头像 李华
网站建设 2026/8/30 13:38:42

蓝桥杯真题解析:从个人所得税计算看边界条件与浮点数精度处理

1. 项目概述&#xff1a;从一道蓝桥杯真题看编程中的“边界”与“精度” 最近在整理蓝桥杯的历年真题&#xff0c;翻到了这道ALGO-465“计算税额”。乍一看&#xff0c;这题目平平无奇&#xff0c;不就是根据收入分段计算个人所得税嘛&#xff0c;很多编程入门书里都有类似的“…

作者头像 李华
网站建设 2026/9/2 9:24:09

PHP大学生心理健康咨询系统:从源码到部署避坑全解析

简介&#xff1a;心理健康咨询系统作为高校信息化建设的重要应用&#xff0c;通常涉及多角色权限管理、预约调度、测评数据追溯等核心需求。基于PHP与ThinkPHP框架实现这类系统&#xff0c;既能快速落地&#xff0c;又能覆盖从用户认证到状态机设计的完整技术链路。在实际部署中…

作者头像 李华
网站建设 2026/8/30 13:36:49

多模态情感分析系统:融合文本语音图像视频的完整实践

简介&#xff1a;情感分析是自然语言处理与人工智能领域的重要研究方向&#xff0c;传统方法主要依赖文本&#xff0c;但真实场景中情绪往往通过语音语调、面部表情和视频动态等多通道信息综合表达。多模态情感分析通过融合文本、语音、图像和视频特征&#xff0c;能够捕捉更完…

作者头像 李华
网站建设 2026/8/30 16:44:56

LTL到LTLf+翻译:用有限迹技术实现无限迹目标

在时序逻辑的实际项目中&#xff0c;我们经常会遇到两种“世界观”打架的情况&#xff1a;一边是需要描述无限长时间行为的 LTL&#xff08;Linear Temporal Logic&#xff09;&#xff0c;另一边是只能描述有限时间行为的 LTLf / LTLf。做智能体规划、反应式系统合成、运行时监…

作者头像 李华