)
一、为什么要做跨平台AI视觉上位机在工业自动化项目里AI视觉检测早已从“锦上添花”变成了产线标配。但过去两年我在十几个项目里反复遇到同一个死局客户产线既有Windows工控机兼容老PLC、Halcon授权又有Linux/国产工控机降本、信创要求两套代码维护成本直接翻倍传统方案用C#做上位机UIPython跑YOLO推理Socket传结果延迟高、进程易崩、现场运维要同时维护两个运行时换平台就要重写UI、重适配串口/CAN、重调推理环境一个项目移植周期动辄半个月现场调试全是坑。今年我们把整套方案重构了一遍基于.NET 8 Avalonia ONNX Runtime实现了一套C#代码同时部署Windows、Linux、国产工控机AI视觉推理完全原生实现零Python依赖代码复用率超过92%。目前已经在3条汽车零部件检测产线、2条3C外观检测产线稳定运行超过6个月。本文把完整的架构设计、核心实现、部署流程和踩坑清单全部整理出来所有代码和配置都经过生产环境验证。二、整体架构五层分层一次编译多端运行整个系统采用分层解耦设计核心原则是业务逻辑与平台实现完全隔离所有平台差异都收敛在最底层的抽象层中。graph TD A[应用层AI视觉上位机UI] -- B[业务逻辑层检测流程/数据管理/报警逻辑] B -- C[核心能力层] C -- C1[AI推理引擎ONNX Runtime] C -- C2[图像处理OpenCVSharp] C -- C3[设备通信串口/CAN/OPC UA/Modbus] C -- C4[数据存储SQLite/日志] C -- D[跨平台抽象层] D -- D1[UI渲染抽象Avalonia] D -- D2[硬件接口抽象平台适配] D -- D3[系统API抽象文件/进程/权限] D -- E[硬件与OS层] E -- E1[Windows 工控机 x64/ARM64] E -- E2[Linux 工控机 x64/ARM64] E -- E3[国产系统统信/银河麒麟]架构设计的三个核心决策UI层统一用Avalonia放弃WPF/WinFormsWPF只能跑WindowsMAUI更偏向消费端移动设备工业场景的触控屏、无桌面嵌入式环境、长时运行稳定性都不如Avalonia。它支持X11/Wayland/DRM直出能直接跑在无桌面的Linux工控机上XAML语法和WPF高度接近原有WPF代码迁移成本很低。AI推理统一ONNX Runtime彻底去掉Python不管是Windows还是LinuxCPU还是GPU都用同一套ONNX模型、同一套C#推理代码。ONNX Runtime官方提供了x64/ARM64的原生库支持CUDA、OpenVINO、TensorRT等加速方案性能比Python调用ONNX高5%-10%没有GIL锁多并发场景优势更明显。所有硬件接口做抽象平台差异下沉到底层串口、CAN、数字IO、相机SDK都定义统一接口通过依赖注入根据运行平台注入不同实现。业务层完全感知不到平台差异新增平台只需要加一个实现类不需要修改业务代码。三、核心模块的生产级实现3.1 跨平台UI层从WPF到Avalonia的工业级适配Avalonia的跨平台能力很强但工业场景有很多细节需要单独处理直接用默认配置大概率会在现场翻车。1UI与业务完全分离采用MVVM架构ViewModel层完全不引用任何平台相关的API所有平台操作都通过接口注入。这样不仅方便单元测试而且UI崩溃不会影响底层的检测流程和设备通信。// 平台接口抽象业务层只依赖这个 public interface IPlatformService { string GetSerialPortMapping(string logicalPort); string GetAppDataPath(); void SetBootAutoStart(bool enable); } // Windows 实现 public class WindowsPlatformService : IPlatformService { ... } // Linux 实现 public class LinuxPlatformService : IPlatformService { ... }2嵌入式Linux无桌面部署很多Linux工控机没有安装桌面环境Avalonia支持直接通过DRM/KMS渲染不需要X11/Wayland。发布时只需要在入口处调用StartLinuxDrm就能直接输出到工业触摸屏。// Program.cs 跨平台入口 public static int Main(string[] args) { if (OperatingSystem.IsLinux() !args.Contains(--windowed)) { // 无桌面DRM模式直接渲染到屏幕 return BuildAvaloniaApp() .StartLinuxDrm(args, DRMOutputOptions.Default); } return BuildAvaloniaApp() .StartWithClassicDesktopLifetime(args); }3工业触摸屏适配工业现场操作员戴劳保手套操作默认的按钮点击区域太小必须统一扩大点击热区同时要关闭系统级的触摸手势避免误操作。!-- 工业按钮样式扩大点击区域 -- Style TargetTypeButton x:KeyIndustrialButton Setter PropertyPadding Value24,16/ Setter PropertyMinHeight Value56/ Setter PropertyMinWidth Value120/ Setter PropertyFontSize Value18/ /Style3.2 AI推理引擎C#原生实现跨平台性能一致这是整套方案的核心。我们彻底抛弃了“C#调Python”的中转方案所有推理逻辑都用C#原生实现Windows和Linux使用完全相同的模型文件和推理代码。1推理引擎选型与配置我们选用Microsoft.ML.OnnxRuntime托管包它是官方维护的C#绑定性能和兼容性最好。会话配置根据平台自动选择最优执行提供器。public class YoloInferenceService : IDisposable { private readonly InferenceSession _session; private readonly string _modelPath; public YoloInferenceService(string modelPath, bool useGpu false) { _modelPath modelPath; var sessionOptions new SessionOptions { ExecutionMode ExecutionMode.Parallel, GraphOptimizationLevel GraphOptimizationLevel.ORT_ENABLE_EXTENDED, MemoryPattern true }; // 平台自动选择加速方案 if (useGpu OperatingSystem.IsWindows()) { sessionOptions.AppendExecutionProvider_CUDA(0); } else if (useGpu OperatingSystem.IsLinux()) { // Linux下优先OpenVINO兼容Intel工控机 sessionOptions.AppendExecutionProvider_OpenVINO(CPU); } else { sessionOptions.AppendExecutionProvider_CPU(); } _session new InferenceSession(modelPath, sessionOptions); } }2模型量化与跨平台一致性工控机大多是CPU推理必须对ONNX模型做INT8量化。量化后模型体积减小75%推理速度提升1.5-2倍精度损失控制在1%以内完全满足工业检测要求。关键注意点模型导出时固定opset版本为12-17不要盲目用最新版避免Linux下算子不支持量化校准集必须使用现场采集的真实产线图片不要用公开数据集统一使用RGB通道输入OpenCV读取的BGR图像必须显式转换否则检测结果坐标和类别全错。3零拷贝内存优化高频推理场景下频繁创建销毁张量会产生大量内存碎片。我们使用OrtValue复用输入输出缓冲区结合.NET的Memorybyte实现零拷贝长时间运行内存占用稳定。实测在i5-12400工控机上YOLOv12n INT8模型单帧推理耗时28ms帧率稳定30内存峰值150MB以内连续运行72小时无内存泄漏。3.3 设备通信层跨平台硬件接口抽象工业上位机离不开串口、CAN、PLC通信这也是跨平台移植最容易踩坑的地方。Windows的端口名是COM3Linux下是/dev/ttyUSB0如果硬编码到代码里换平台直接崩溃。1串口通信统一封装public interface ISerialPortService { bool Open(string logicalPort, int baudRate); void Send(byte[] data); event Actionbyte[] DataReceived; } public class CrossPlatformSerialPort : ISerialPortService { public bool Open(string logicalPort, int baudRate) { // 平台自动映射端口名 string physicalPort RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? logicalPort : $/dev/tty{logicalPort.ToUpper().Replace(COM, USB)}; // 权限检查Linux下需要dialout组权限 if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { if (!File.Exists(physicalPort)) throw new IOException($串口设备不存在{physicalPort}); } var serialPort new SerialPort(physicalPort, baudRate); serialPort.Open(); return true; } }2CAN与OPC UA的跨平台支持CAN总线Windows用周立功CAN卡Linux用SocketCAN统一封装为ICanService接口业务层只发收报文OPC UA使用OPC Foundation官方跨平台库Windows和Linux完全通用不需要任何平台适配Modbus TCP/RTU基于NModbus封装跨平台无差异。3.4 图像采集与处理工业相机SDK大多同时提供Windows和Linux版本我们把相机采集封装为统一的ICameraService支持海康、大恒、Basler等主流相机。图像处理统一使用OpenCVSharp4它的跨平台支持非常成熟Windows下用OpenCV的dllLinux下安装libopencv-dev即可。需要注意Linux下不要用System.Drawing.Common微软已经停止跨平台支持工业场景会有各种GDI依赖问题图像格式统一用Mat不要频繁转换为Bitmap避免内存拷贝相机采集到的图像直接写入ONNX输入缓冲区实现采集-推理零拷贝。四、跨平台部署与运维指南4.1 发布配置采用.NET自包含发布模式目标机器不需要安装.NET运行时拷贝过去就能运行。# Windows x64 发布 dotnet publish -c Release -r win-x64 --self-contained true -p:PublishSingleFiletrue # Linux x64 发布 dotnet publish -c Release -r linux-x64 --self-contained true -p:PublishSingleFiletrue # Linux ARM64 发布飞腾/瑞芯微工控机 dotnet publish -c Release -r linux-arm64 --self-contained true4.2 Linux工控机部署步骤把发布包拷贝到/opt/vision-inspector/目录给可执行文件加执行权限chmod x VisionInspector串口权限把当前用户加入dialout组避免每次用sudo配置systemd服务实现开机自启和崩溃自动重启无桌面环境下直接运行DRM模式需要root权限或者video组权限。4.3 容器化部署可选对于多设备批量部署可以打包成Docker镜像Linux工控机直接拉取运行。Windows容器也支持但工业现场用得不多。FROM mcr.microsoft.com/dotnet/runtime:8.0-jammy WORKDIR /app COPY publish/ . RUN apt-get update apt-get install -y libopencv-dev libc6-dev ENTRYPOINT [./VisionInspector]五、生产环境踩坑30这10个最致命跨平台的坑90%都出在平台差异的细节上很多问题在开发环境不会出现到了现场才集中爆发。这里列出出现频率最高、影响最大的10个。坑点现象根因解决方案串口找不到设备Linux下启动报“端口不存在”Windows是COMxLinux是/dev/ttyUSBx硬编码端口名按平台动态映射端口提供端口扫描和手动选择界面程序启动闪退Linux工控机双击没反应日志报GDI错误使用了System.Drawing.CommonLinux缺少libgdiplus全部替换为OpenCVSharp移除所有System.Drawing引用推理结果全错检测框位置偏移、类别识别错误OpenCV读取BGR模型输入RGB通道顺序反了推理前显式转换通道统一预处理逻辑无桌面环境无法运行Linux工控机没装桌面UI启动失败默认使用X11渲染没有X Server启用Avalonia DRM模式直接渲染到帧缓冲触摸屏点击偏移屏幕旋转后触摸坐标错位DRM模式下触摸坐标没有跟随屏幕旋转配置DrmOutputOptions.OrientationAvalonia会自动转换触摸坐标模型加载失败Linux下报“算子不支持”ONNX模型opset版本过高Linux原生库不支持导出模型固定opset12避免使用自定义算子长时间运行内存泄漏运行几小时后内存持续上涨频繁创建InferenceSession和Mat对象全局单例会话复用张量缓冲区及时释放非托管资源老工控机启动崩溃报“非法指令”错误新版ONNX Runtime需要AVX2指令集老CPU不支持降级到ONNX Runtime 1.15版本该版本兼容SSE指令集CAN通信失败Linux下CAN卡无法通信Windows用厂商SDKLinux需要SocketCAN统一封装ICanServiceLinux下使用SocketCAN实现中文显示乱码Linux下界面中文变成方块系统缺少中文字体打包时嵌入思源黑体Avalonia指定自定义字体六、性能实测Windows vs Linux我们在同配置硬件i5-12400、16G内存、集显上分别测试了Windows 10 IoT和Ubuntu 22.04的推理性能模型为YOLOv12n INT8输入640×640。指标Windows 10 IoTUbuntu 22.04差异单帧推理耗时28.1ms29.3ms4.3%平均帧率35.6 FPS34.1 FPS-4.2%内存峰值148 MB156 MB5.4%程序启动耗时1.2s1.5s25%72小时内存增长8MB11MB均在正常范围可以看到Linux下的推理性能和Windows基本持平差距在5%以内完全满足工业现场的实时性要求。如果搭配Intel OpenVINO加速Linux下的CPU推理性能还能再提升20%-30%。七、总结与后续扩展这套统一架构最大的价值不是“能跑”而是把跨平台的复杂度全部收敛到底层业务开发人员完全不需要关心平台差异。新增一个检测工位只需要写一次业务逻辑就能同时部署到Windows和Linux工控机上项目交付周期缩短了60%。后续我们还在做两个方向的优化模型热更新支持产线不停机更新AI模型不需要重启上位机边缘集群调度多台工控机统一管理模型、配置和检测数据国产化深度适配针对飞腾、鲲鹏、龙芯平台做指令集优化。如果你的项目也面临Windows/Linux多平台部署、AI视觉集成、老系统改造的问题这套架构可以直接参考落地。