上位机系统架构 | 如何设计一个高效的多相机管理系统

在许多应用中,我们需要同时控制和管理多个相机设备,比如在工业自动化、安防监控、机器视觉等领域。这就需要我们设计一个高效的多相机管理系统。今天,我将带你了解如何利用C#设计一个这样的系统。

设计思路

我们的设计思路是将每一个相机看作一个对象,然后使用一个管理器来统一管理这些相机对象。这样,我们就可以通过管理器来控制和管理所有的相机设备,而不需要为每一个设备编写单独的代码。

具体来说,我们需要设计三个类:一个抽象的相机类,一个具体的相机类,以及一个相机管理器类。

抽象相机类

抽象相机类定义了相机设备的基本功能,包括打开和关闭相机,开始和停止图像采集,设置相机标记,以及软触发设备。此外,这个类还定义了两个事件:设备丢失事件和图像就绪事件。这两个事件可以帮助我们在设备丢失或图像就绪时执行相应的操作。

以下是抽象相机类的代码:

cs 复制代码
public abstract class ICameraAbstract
{
    //相机唯一标志
    public string CamMark { get; protected set; } = "";
    public bool IsVirtualCamera { get; protected set; } = false;
    //相机初始化成功标志
    public bool InitialSuccess { get; protected set; } = false;
    //相机掉线事件
    public abstract event Action<string> DeviceLostEvent;
    //相机采集图像后发出相关信息事件
    public abstract event Action<string, ImageReceived> ImageReadyEvent;
    //设置相机唯一标志
    public abstract void SetCamMark(string mark);
    //打开相机
    public abstract void Open();
    public abstract void Close();
    //开始采集图像
    public abstract void StartAcquisition(EnumTriggerMode mode);
    //停止采集图像
    public abstract void StopAcquisition();
    //相机软触发采集图像
    public abstract int SoftwareTriggerDevice();
}

具体相机类

具体相机类继承自抽象相机类,实现了相机的具体功能。这个类使用了一个静态的设备列表和一个选定的设备对象来管理相机设备。在打开设备的方法中,这个类会打开选定的设备,并订阅设备的图像采集事件和设备异常事件。在处理图像采集事件的方法中,这个类会将采集到的图像保存为图像对象,并异步触发图像就绪事件。

以下是具体相机类的部分代码:

cs 复制代码
class CameraMvs : ICameraAbstract
{
    public override event Action<string> DeviceLostEvent;
    public override event Action<string, ImageReceived> ImageReadyEvent;
    static List<IDevice> devices= DeviceEnumerator.EnumDevices();
    static IDevice SelectedDevice;
    public bool isGrabbing = false;        // ch:是否正在取图 | en: Grabbing flag
...
    public override void Open()
    {
        if (devices != null && devices.Count > 0)
        {
            SelectedDevice = devices.FirstOrDefault(p => p.DeviceInfo.SerialNumber == CamMark);
            if (SelectedDevice != null)
            {
                var ret = SelectedDevice.Open();
                if (ret != MvError.MV_OK)
                {
                    Log.Error($"Camera类的InitService方法打开设备失败,信息:{ret}");
                    return;
                }
                SelectedDevice.StreamGrabber.FrameGrabedEvent += StreamGrabber_FrameGrabedEvent;
                SelectedDevice.DeviceExceptionEvent += Selecteddevice_DeviceExceptionEvent;
            }
            InitialSuccess = true;
        }
    }
...
}

相机管理器类

相机管理器类是一个单例类,用于管理所有的相机设备。这个类维护了一个相机对象的字典,字典的键是相机的标记,字典的值是相机对象。这个类提供了一系列方法来控制和管理相机设备,包括初始化和打开相机,开始和停止图像采集,以及软触发设备。此外,这个类还定义了一个图像就绪事件,当任何一个相机设备的图像就绪时,这个事件都会被触发。

以下是相机管理器类的部分代码:

cs 复制代码
public class CamerasManagement
{
    private static readonly object _padlock = new object();
    private static CamerasManagement _instance = null;
    public delegate void ImageReadyEventHandler(int camIndex, ImageReceived img);
    public event ImageReadyEventHandler ImageReadyEvent;
    ImageReadyEventHandler _TheCallback = null;
    public event Action<string> DevicesLostEvent;
    
    public Dictionary<string, ICameraAbstract> DicCamera = new Dictionary<string, ICameraAbstract>();
...
}

代码运行

最后,我们可以通过以下代码来测试我们的相机管理系统:

cs 复制代码
CamerasManagement.GetInstance().StartAcquisition(GetCamImage);
private void GetCamImage(int camIndex, ImageReceived img)
{
    Log.Information("GetCamImage类已实现,image 宽度:"+img.Width);
}

总结

通过这种设计,我们可以方便地控制和管理多个相机设备,而无需为每个设备编写单独的代码。此外,我们还可以利用事件和异步操作来提高应用程序的响应性,以及使用抽象类和接口来方便地扩展和修改代码。希望这篇文章能帮助你更好地理解如何设计一个高效的多相机管理系统。

如果你对这个主题感兴趣,或者有任何疑问或建议,欢迎在评论区留言。让我们一起学习和进步!

相关推荐
code bean1 小时前
【C#基础】函数传参大总结
服务器·开发语言·c#
ling1s4 小时前
C#基础(13)结构体
前端·c#
.Net Core 爱好者4 小时前
Redis实践之缓存:设置缓存过期策略
java·redis·缓存·c#·.net
云草桑4 小时前
逆向工程 反编译 C# net core
前端·c#·反编译·逆向工程
充值内卷6 小时前
WPF入门教学四 WPF控件概述
windows·ui·wpf
指尖流烟6 小时前
C#调用图表的使用方法
开发语言·c#
friklogff8 小时前
【无标题】云端之C#:全面解析6种云服务提供商的SDK
开发语言·flask·c#
c#上位机9 小时前
C#事件的用法
java·javascript·c#
chnyi6_ya9 小时前
一些写leetcode的笔记
笔记·leetcode·c#