别再说 C做不了工业视觉! 多相机 + 插件架构 + 全流程管控全落地

发布日期:2026-02-12 17:26    点击次数:117

工业视觉检测、自动化引导、精密测量等场景中,一套稳定、可扩展的上位机软件框架是项目落地的关键。不同于简单的图像显示工具,工业级视觉软件需要集成相机管理、算法插件、通信控制、运行调度、用户权限等复杂功能。

本文将介绍一个真实可用的计算机视觉界面框架的核心结构与设计理念。

项目介绍

项目是一个面向工业自动化的计算机视觉平台,采用模块化架构,支持多相机、多工位、多算法协同工作。其主界面基于 WinForm 开发,使用 Dock 布局实现灵活的窗口管理,并通过插件机制加载各类视觉工具(如对位、测量、识别等)。

整个系统分为多个层级:核心库(VisionCore)、辅助工具(RexHelps)、常量定义(RexConst)、UI 控件(RexControl)以及按功能划分的插件目录(Plugin)。

从项目结构,将功能解耦:

Main:主程序入口

Plugin:包含几何测量、检测识别、通信工具等十余类插件

Camera:支持海康、Basler 等主流工业相机

Control:自定义 UI 控件库

这种分层让系统易于维护和扩展。

项目功能

1、项目管理

新建、打开、保存视觉项目(.RV 格式),支持自动启动配置

2、运行控制

提供"单次运行""循环运行""停止运行"三种执行模式

3、资源调度

动态加载主显示窗体(FrmShow),用于实时图像展示

4、系统设置

支持画布数量配置、相机参数、通信协议、系统变量等

5、状态监控

实时显示 CPU 使用率、内存占用、运行时长、磁盘空间等

6、安全机制

项目关闭前提示保存,支持用户登录与界面锁定

特别值得注意的是,系统通过 ShowMsg.ShowRImageEvent事件机制,将底层图像数据推送到 UI 层,实现解耦。

项目特点

插件化设计:所有视觉工具(如对位、测量)均以插件形式存在,主程序无需硬编码具体功能。

多屏支持:通过mScreenNum动态配置显示画布数量,适应单相机或多工位场景。

健壮性保障:项目未保存时阻止关闭,运行异常时弹出友好提示,避免直接崩溃。

工业友好:界面元素命名贴近工程语言(如"通讯设置""相机设置"),降低用户学习成本。

性能监控内置**:自动采集 CPU、内存、磁盘信息,便于现场调试与故障排查。

项目技术

使用 DockForm作为基类,实现类似 Visual Studio 的可停靠窗口布局

通过 TopLevel = false将子窗体嵌入 Panel,构建主-子视图结构

利用 Invoke确保跨线程 UI 更新安全(如ShowImgae方法)

借助 PerformanceCounter实时读取系统资源占用

采用序列化方式保存/加载项目数据(Sol.SaveData/Sol.ReadData)

引入事件总线(SetEComEvent)实现模块间松耦合通信

代码中还包含一些实用细节,如 ESC 键恢复窗口位置、淡入淡出动画(虽被注释)、磁盘空间百分比计算等。

项目代码

private async void RunMemoryCPU

{

TimeSpan RunTime = new TimeSpan;

Process CurrentProcess = Process.GetProcessesByName("RexVision")[0];

var CurrentProcessName = Process.GetCurrentProcess.ProcessName;

var CurrentProcessCpu = new PerformanceCounter("Process", "% Processor Time", CurrentProcessName);

var TotalCurrentCpu = new PerformanceCounter("Processor", "% Processor Time", "_Total", true);

var CurrentProcessMemory = new PerformanceCounter("Process", "Working Set - Private", CurrentProcessName);

await Task.Run(async =>

{

while (!IsClose)

{

await Task.Delay(5000);

try

{

BeginInvoke(new Action( =>

{

RunTime += DateTime.Now - RunStartTime;

RunStartTime = DateTime.Now;

ts_RunTime.Text = string.Format("运行:{0}H", RunTime.TotalHours.ToString("F2"));

tS_time.Text = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss ") + GetWeekName;

Run_CPU.Text = "CPU:" + (CurrentProcessCpu.NextValue / Environment.ProcessorCount).ToString("F2") + " %";

Run_Memory.Text = "内存:" + (CurrentProcessMemory.NextValue / 1024 / 1024).ToString("F2") + " MB";

ts_ProjPath.Text = Sol.mSavePath;

ts_Drive.Text="D盘:"+(int)(((double)(RDrive.GetHardDiskFreeSpace("D") / 1024 / 1024 / 1024) / (double)(RDrive.GetHardDiskSpace("D") / 1024 / 1024 / 1024)) * 100)+"%";

}));

}

catch (Exception ex)

{

Run_CPU.Text = "0%";

Run_Memory.Text = "0 KB";

this.ShowWarningNotifier(ex + "\r\n 性能计数器异常,请输入CMD运行后输入LODCTR/R");

}

}

});

}

项目效果

启动后,软件默认加载"AutoStart"项目(若配置开启),主界面中央为图像显示区(FrmShow),顶部工具栏提供运行控制,底部状态栏持续更新系统信息。可通过菜单或工具按钮调出各类插件窗口,进行算法配置、参数调试等操作。整个界面响应流畅,即使在长时间运行下也能保持稳定。

当有图像数据产生时(如相机触发或仿真输入),系统会自动将其推送到主显示区,实现"所见即所得"的调试体验。

系统主页

工具箱

相机设置

变量设置

通讯设置

画布设置

系统设置

项目源码

主窗体核心逻辑集中在 FormMain.cs,关键方法包括:

ShowUIForm:初始化并嵌入主显示窗体

OpenProj/CreateProj:项目加载与创建

ToolStripButton_Click:处理工具栏命令(运行、保存、设置等)

ShowImgae:接收图像事件并刷新 UI

完整源码结构清晰,命名规范(如 mMainShow、mFormList),配合合理的函数拆分,可读性较强。对于希望开发自有视觉平台的大家们,这是一个极具参考价值的项目。

为了防止丢失,可以在评论区留言关键字「视觉框架」,即可获取完整源码地址。

总结

项目的主窗体设计体现工业软件开发的典型思路:稳定优先、功能聚合、扩展开放。它没有追求炫酷的界面,而是聚焦于解决实际工程问题——如何高效组织视觉流程、如何安全管理项目数据、如何方便地集成新算法。这种"务实而不花哨"的风格,恰恰是工控软件最需要的品质。

对于正在开发机器视觉上位机的团队来说,其架构思想和实现细节都值得深入借鉴。