1.创建相机数据类
public class GlobelPara
{
public static Hardware Hardware = new Hardware();
}
public class Hardware
{
public ConcurrentDictionary<string, CameraData> CameraData { get; set; } = new ConcurrentDictionary<string, CameraData>();
}
public class CameraUser
{
//存储图像队列
public ConcurrentQueue<HObject> ImageData { get; set; } = new ConcurrentQueue<HObject>();
public string Name { get; set; }
public int Height { get; set; }
public int Width { get; set; }
public int Index { get; set; }
public bool Enable { get; set; }
public bool Star { get; set; }
public bool RBG { get; set; }
public bool End { get; set; }
}
public class CameraData
{
public string Name { get; set; }
public CameraType Type { get; set; }
public CameraImageType RBG { get; set; }
public CameraSoftType SoftTrigger { get; set; }
public int Exposure { get; set; }
public int Gain { get; set; }
public int Width { get; set; }
public int Height { get; set; }
public string Description { get; set; }
}
public enum CameraType
{
Hik,
Balser,
DH,
Sim,
}
public enum CameraSoftType
{
Soft,
Hard,
}
public enum CameraImageType
{
Gray,
RBG,
}
2.创建抽象抽象工厂模式的基类
public abstract class MyCameraBase
{
public CameraUser Camera = new CameraUser();
public MyCameraBase(string name)
{
this.Camera.Name = name;
}
~MyCameraBase()
{
Close();
}
public abstract bool Enum();
public abstract bool Init();
public abstract void Close();
public abstract double GetExpose();
public abstract void SetExpose(double value);
public abstract double GetGain();
public abstract void SetGain(double value);
protected abstract bool SoftTriggerOnce();
public abstract bool SetTriggerMode(bool value);
public bool GetImage(bool soft)
{
if (soft)
return SoftTriggerOnce();
else
return true;
}
}
3.实现子类:海康相机
public class CameraHik : MyCameraBase
{
private cbOutputExdelegate ImageCallback;
List<CCameraInfo> m_ltDeviceList = new List<CCameraInfo>();
public CameraHik(string name) : base(name)
{
}
public CCamera cCamera { get; set; }
public override bool Enum()
{
List<CameraBase> listCam = new List<CameraBase>();
int nRet = CSystem.EnumDevices(CSystem.MV_GIGE_DEVICE | CSystem.MV_USB_DEVICE, ref m_ltDeviceList);
return nRet == CErrorDefine.MV_OK;
}
public override bool Init()
{
bool res = false;
foreach (var item in m_ltDeviceList)
{
if (((CGigECameraInfo)item).UserDefinedName != Camera.Name)
continue;
cCamera = new CCamera();
CCameraInfo device = item;
int nRet = cCamera.CreateHandle(ref device);
nRet = cCamera.OpenDevice();
if (CErrorDefine.MV_OK != nRet)
{
cCamera.DestroyHandle();
break;
}
// ch:设置采集连续模式 | en:Set Continues Aquisition Mode
cCamera.SetEnumValue("TriggerMode", (uint)MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON);
cCamera.SetEnumValue("TriggerSource", (uint)MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE);
cCamera.SetEnumValue("AcquisitionMode", (uint)MV_CAM_ACQUISITION_MODE.MV_ACQ_MODE_CONTINUOUS);
ImageCallback = new cbOutputExdelegate(ImageCallbackFunc);
cCamera.RegisterImageCallBackEx(ImageCallback, IntPtr.Zero);
nRet = cCamera.StartGrabbing();
res = nRet == CErrorDefine.MV_OK;
}
return res;
}
public override void Close()
{
try
{
cCamera?.StopGrabbing();
cCamera?.CloseDevice();
cCamera?.DestroyHandle();
}
catch (Exception)
{
}
}
public override double GetExpose()
{
CFloatValue pcFloatValue = new CFloatValue();
int nRet = cCamera.GetFloatValue("ExposureTime", ref pcFloatValue);
return pcFloatValue.CurValue;
}
public override double GetGain()
{
CFloatValue pcFloatValue = new CFloatValue();
int nRet = cCamera.GetFloatValue("Gain", ref pcFloatValue);
return pcFloatValue.CurValue;
}
public override void SetExpose(double value)
{
int nRet = cCamera.SetFloatValue("ExposureTime", (float)(value));
if (nRet != CErrorDefine.MV_OK)
{
//ShowErrorMsg("Set Exposure Time Fail!", nRet);
}
}
public override void SetGain(double value)
{
int nRet = cCamera.SetFloatValue("Gain", (float)(value));
if (nRet != CErrorDefine.MV_OK)
{
//ShowErrorMsg("Set Exposure Time Fail!", nRet);
}
}
protected override bool SoftTriggerOnce()
{
int nRet = cCamera.SetCommandValue("TriggerSoftware");
return nRet == CErrorDefine.MV_OK;
}
public override bool SetTriggerMode(bool value)
{
return false;
}
private void ImageCallbackFunc(IntPtr pData, ref MV_FRAME_OUT_INFO_EX pFrameInfo, IntPtr pUser)
{
// if(Camera.Enable)
{
HObject hObject = new HObject();
if (Camera.RBG)
{
HOperatorSet.GenImageInterleaved(out hObject, pData, "rgb", (int)pFrameInfo.nWidth, (int)pFrameInfo.nHeight, 0, "byte", (int)pFrameInfo.nWidth, (int)pFrameInfo.nHeight, 0, 0, -1, 0);
}
else
{
HOperatorSet.GenImage1(out hObject, "byte", (int)pFrameInfo.nWidth, (int)pFrameInfo.nHeight, pData);
}
Camera.ImageData.Enqueue(hObject);
Camera.Star = false;
Camera.End = true;
}
}
}
4.创建相机的管理类
public class CameraMgr
{
private static object obj = new object();
private static CameraMgr _CameraMgr;
private CameraMgr()
{
}
~CameraMgr()
{
Close();
}
public static CameraMgr Instance
{
get
{
lock (obj)
{
if (_CameraMgr == null)
{
if (_CameraMgr == null)
{
_CameraMgr = new CameraMgr();
}
}
return _CameraMgr;
}
}
}
public ConcurrentDictionary<string, MyCameraBase> cameraList = new ConcurrentDictionary<string, MyCameraBase>();
public bool InitCamera()
{
try
{
// string systemCard = GlobelPara.SystemData.ConfigBasePath + "Motion.xml";
// XMLBase.Read(systemCard);
foreach (var item in GlobelPara.Hardware.CameraData)
{
Assembly assembly = Assembly.GetAssembly(typeof(MyCameraBase));
string name = $"System.Camera.Camera{item.Value.Type}";
//Motion_Advantech
Type type = assembly.GetType(name);
bool flag = type == null;
if (flag)
{
throw new Exception(string.Format($"相机类型:{item.Value.Type} 名称:{item.Key}找不到可用的封装类,System.Camera.dll是否正确或配置错误?"));
}
object[] args = new object[]
{
item.Key,
};
cameraList.TryAdd(item.Key, Activator.CreateInstance(type, args) as MyCameraBase);
bool res = cameraList[item.Key].Enum();
res &= cameraList[item.Key].Init();
if(!res)
{
throw new Exception("初始化失败");
}
}
return true;
}
catch (Exception ex)
{
// DialogMgr.Instance.ShowErr($"初始化相机失败,{ex}");
return false;
}
}
public MyCameraBase GetCamera(string name)
{
return cameraList[name];
}
//public bool Enum(string name)
//{
// return cameraList[name].Enum();
//}
//public bool Init(string name)
//{
// return cameraList[name].Init();
//}
public void Close(string name = "")
{
if (name == "")
{
foreach (var item in cameraList)
{
item.Value.Close();
}
}
else
{
cameraList[name].Close();
}
}
public double GetExpose(string name)
{
return cameraList[name].GetExpose();
}
public void SetExpose(string name, double value)
{
cameraList[name].SetExpose(value);
}
public double GetGain(string name)
{
return cameraList[name].GetGain();
}
public void SetGain(string name, double value)
{
cameraList[name].SetGain(value);
}
public bool SetTriggerMode(string name, bool value)
{
return cameraList[name].GetImage(value);
}
public bool GetImage(string name, bool soft)
{
return cameraList[name].GetImage(soft);
}
public bool GetImage(string name)
{
bool soft = GlobelPara.Hardware.CameraData[name].SoftTrigger == CameraSoftType.Soft;
return cameraList[name].GetImage(soft);
}
}
5.实际项目应用
//初始化数据,可以用配置文件方式读取
GlobelPara.Hardware.CameraData.TryAdd("相机1",new Base.CameraData() {Name="相机1", RBG= CameraImageType.Gray, SoftTrigger= CameraSoftType.Soft, Type= CameraType.Hik });
//设置曝光 增益 取图=》不等待的方式
//图片会存储在 CameraMgr.Instance.cameraList["相机1"].Camera.ImageData队列中
CameraMgr.Instance.SetExpose("相机1",10000);
CameraMgr.Instance.SetGain("相机1", 1);
CameraMgr.Instance.GetCamera("相机1");
//等待取图完成模式
CameraMgr.Instance.SetExpose("相机1", 10000);
CameraMgr.Instance.SetGain("相机1", 1);
CameraMgr.Instance.cameraList["相机1"].Camera.End = false;
CameraMgr.Instance.GetCamera("相机1");
while (true)
{
if (CameraMgr.Instance.cameraList["相机1"].Camera.ImageData.Count > 0)
{
break;
}
hread.Sleep(10);
}