工业相机和算法库太多太杂?这个 WPF 视觉平台把它们统一管起来了

前言

工业视觉领域,开发一套稳定、灵活且易于维护的平台从来不是一件容易的事。不同品牌的相机、多样的图像算法库、复杂的场景配置逻辑,常常让开发者陷入"适配地狱"。而更头疼的是,每次更换硬件或算法框架,几乎都要重写大半代码。有没有一种方式,能把这些差异封装起来,让上层逻辑专注业务本身?

本文推荐一个用插件化架构和清晰的抽象接口,为工业视觉应用提供一个真正可扩展的基础平台。

项目介绍

一个基于 .NET 和 WPF 开发的工业视觉开发平台,核心目标是解耦相机驱动与视觉算法框架。通过定义统一的 ICamera 和 IVisionFrame 接口,平台支持动态加载不同厂商的 SDK(如 uEye、Hik、Pylon 等)以及主流视觉库(如 HALCON、VisionPro)。主窗口(MainWindow)作为调度中心,负责管理场景、切换环境、调用执行流程,而所有具体实现则通过反射从独立 DLL 中加载,真正做到"即插即用"。

项目功能

1、多相机支持

自动扫描指定目录下的相机 SDK 插件,支持物理相机与虚拟图像文件夹(用于测试)。

2、多视觉框架切换

可在 HALCON、VisionPro 等之间动态切换,无需重启应用。

3、场景管理

每个检测任务封装为一个"Scene",包含相机绑定、算法流程、参数配置,支持创建、修改、删除和恢复。

4、标定与相机配置

提供独立窗口进行相机参数调整(曝光、增益、触发模式)和手眼标定操作。

5、运行与调试

选中场景后一键执行,结果实时反馈,错误信息弹窗提示,便于现场调试。

项目特点

最突出的特点是"插件化"和"解耦"。相机和视觉算法不再是硬编码依赖,而是通过工厂类(CameraFactory、VisionFrameFactory)在运行时动态加载。

这意味着,当需要接入一个新的相机品牌,只需按约定编写一个实现 ICamera 的 DLL 放入对应目录,平台就能自动识别。同样,算法模块也可独立升级,不影响主程序。

另外,虚拟相机功能极大提升了开发效率——即使没有真实设备,也能用本地图片模拟采集流程。

项目技术

平台采用 C# + WPF UI,利用 MVVM 模式分离界面与逻辑。

核心技术点包括:

反射与插件机制:通过 Assembly.LoadFrom 动态加载 DLL,按类型名实例化对象。

接口抽象:ICamera 定义了 Connect、Grab、StopGrab 等通用方法,屏蔽底层 SDK 差异。

单例场景管理:SceneManager 以字典形式维护所有 Scene 实例,支持持久化恢复。

资源安全释放:在窗口关闭时主动 StopGrab、DisConnect 并 Dispose 相机对象,防止内存泄漏。

配置文件管理:相机参数和标定数据以 JSON 形式存储,便于版本控制和迁移。

项目代码

相机工厂静态类

/// 
/// 获取所有的相机
///
/// 相机信息列表
public static List GetAllCameras
{
//校验相机SDK是否有效
if (!CameraAssemblys.ContainsKey(DefaultCameraSdkType))
{
thrownew ArgumentException("ECameraSdkType invalid");
}
return CreateInstance(DefaultCameraSdkType).GetDeviceList;
}

///
/// 添加相机
///
/// 相机序列号
///
/// 打开相机失败
///
public static void AddCamera(string cameraSerial)
{
//校验相机SDK是否有效
if (!CameraAssemblys.ContainsKey(DefaultCameraSdkType))
{
thrownew ArgumentException("ECameraSdkType invalid");
}

if (string.IsNullOrEmpty(cameraSerial))
{
thrownew ArgumentException("cameraSerial cannot be null");
}

//如果当前相机已经注册了,则直接返回
if (Cameras.ContainsKey(cameraSerial))
{
return;
}

ICamera camera = CreateInstance(DefaultCameraSdkType);

if (camera.Connect(cameraSerial))
{
Cameras.Add(cameraSerial, camera);
SetToDefaultConfiguration(camera);
return;
}
else
{
thrownew InvalidOperationException($"open camera[{cameraSerial}] err!");
}
}

///
/// 添加所有的相机
///
/// 执行结果
public static void AddAllCamera
{
//校验相机SDK名是否有效
if (!CameraAssemblys.ContainsKey(DefaultCameraSdkType))
{
thrownew ArgumentException("ECameraSdkType invalid");
}

try
{
//添加所有的相机
var devices = GetAllCameras;
foreach (var item in devices)
{
AddCamera(item.SerialNumber);
}
}
catch (Exception)
{
throw;
}
}

///
/// 移除相机
///
/// 相机序列号
public static void RemoveCamera(string cameraSerial)
{
if (Cameras.ContainsKey(cameraSerial))
{
//关闭相机
Cameras[cameraSerial].StopGrab;
Cameras[cameraSerial].DisConnect;
Cameras[cameraSerial].Dispose;

//从列表中移除
Cameras.Remove(cameraSerial);
}
}

///
/// 移除所有的相机
///
public static void RemoveAllCameras
{
foreach (var item in Cameras.Values)
{
item.StopGrab;
item.DisConnect;
item.Dispose;
}
Cameras.Clear;
}

项目效果

可通过下拉框快速切换相机类型和视觉框架。系统会自动加载预设的测试图像目录(如刹车片、眼镜等),直接用于算法验证。创建新场景后,可配置图像源、绑定算法步骤、设置触发逻辑,保存后即可在列表中看到。

系统主页

相机窗口

标定窗口

场景配置

项目源码

项目结构清晰,所有相机 SDK 封装为独立类库,命名规范严格,二次开发极为方便,不管是新增设备支持,还是替换算法引擎,都无需改动主程序。

为了防止丢失,可以在评论区留言关键字「工业相机」,即可获取完整源码地址。

总结

项目没有炫酷的界面或复杂的 AI 功能,而是回归工程本质:解决兼容性问题、提升开发效率、保障系统稳定性。它像一个"视觉中间件",把碎片化的工业硬件和软件整合成统一的服务。对于需要长期维护、频繁迭代的视觉项目来说,这种架构带来的灵活性和可维护性,远比短期开发速度更重要。如果大家正被多品牌设备困扰,不妨看看这个平台的设计思路,或许能为大家打开一扇新的门作为参考。

关键词

、、、C#、、、、、、、、、

最后

如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。也可以加入微信公众号[DotNet技术匠]社区,与其他热爱技术的同行一起交流心得,共同成长!

作者:小码编匠

出处:
gitee.com/smallcore/DotNetCore

声明:网络内容,仅供学习,尊重版权,侵权速删,歉意致谢!

END

觉得有收获?不妨分享让更多人受益

关注「DotNet技术匠」,共同提升技术实力

收藏

分享

在看

展开阅读全文

更新时间:2025-12-22

标签:数码   算法   视觉   相机   工业   平台   项目   场景   窗口   插件   框架

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020- All Rights Reserved. Powered By bs178.com 闽ICP备11008920号
闽公网安备35020302034844号

Top