using HalconDotNet; using MvCamCtrl.NET; using Rs.Framework; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace Rs.Cameras { public class HikCameras { private static HikCameras instance; public static HikCameras Instance { get { if (instance == null) instance = new HikCameras(); return instance; } } private HikCameras() { cbImage = new MyCamera.cbOutputExdelegate(ImageCallBack); } MyCamera.MV_CC_DEVICE_INFO_LIST m_pDeviceList; int apiResult = 0; MyCamera.cbOutputExdelegate cbImage; IntPtr m_BufForDriver = IntPtr.Zero; List cameraInfos = new List(); private void ImageCallBack(IntPtr pData, ref MyCamera.MV_FRAME_OUT_INFO_EX pFrameInfo, IntPtr pUser) { LogHelper.Debug("收到相机数据"); HObject image; HOperatorSet.GenEmptyObj(out image); image.Dispose(); int nIndex = (int)pUser; HOperatorSet.GenImage1(out image, "byte", pFrameInfo.nWidth, pFrameInfo.nHeight, pData); CameraInfo ci = GetCameraInfo(nIndex); if (ci != null) { ci.AddImage(image); } } public List Init() { int nRet = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref m_pDeviceList); if (nRet != 0) { LogHelper.Debug($"MV_CC_EnumDevices_NET ret = {nRet}"); //未找到任何相机 return null; } else if (m_pDeviceList.nDeviceNum>0) { for (int i = 0; i < m_pDeviceList.nDeviceNum; i++) { string cameraInfo = string.Empty; ///获取相机信息 MyCamera.MV_CC_DEVICE_INFO device = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(m_pDeviceList.pDeviceInfo[i], typeof(MyCamera.MV_CC_DEVICE_INFO)); if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE) { MyCamera.MV_GIGE_DEVICE_INFO gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO)MyCamera.ByteToStruct(device.SpecialInfo.stGigEInfo, typeof(MyCamera.MV_GIGE_DEVICE_INFO)); if(!string.IsNullOrEmpty(gigeInfo.chUserDefinedName)) { cameraInfo = gigeInfo.chUserDefinedName; }// gigeInfo.chModelName + " (" + gigeInfo.chSerialNumber + ")"; else { cameraInfo = gigeInfo.chSerialNumber; } } else if (device.nTLayerType == MyCamera.MV_USB_DEVICE) { MyCamera.MV_USB3_DEVICE_INFO usbInfo = (MyCamera.MV_USB3_DEVICE_INFO)MyCamera.ByteToStruct(device.SpecialInfo.stGigEInfo, typeof(MyCamera.MV_USB3_DEVICE_INFO)); if (!string.IsNullOrEmpty(usbInfo.chUserDefinedName)) { cameraInfo = usbInfo.chUserDefinedName; } else { cameraInfo = usbInfo.chSerialNumber; } } MyCamera camera = new MyCamera(); apiResult = camera.MV_CC_CreateDevice_NET(ref device); if (apiResult != 0) { LogHelper.Debug($"MV_CC_CreateDevice_NET ret = {apiResult}"); //MV_CC_CreateDevice_NET fail; //return ECameraErrorCode.CreateDeviceFail; continue; } apiResult = camera.MV_CC_OpenDevice_NET(); if (apiResult != 0) { LogHelper.Debug($"MV_CC_OpenDevice_NET ret = {apiResult}"); //return ECameraErrorCode.OpenDeviceFail; continue; } if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE) { int nPacketSize = camera.MV_CC_GetOptimalPacketSize_NET(); if (nPacketSize > 0) { nRet = camera.MV_CC_SetIntValue_NET("GevSCPSPacketSize", (uint)nPacketSize); if (nRet != MyCamera.MV_OK) { LogHelper.Debug($"MV_CC_SetIntValue_NET GevSCPSPacketSize ret = {apiResult}"); //return ECameraErrorCode.GevSCPSPacketSizeFail; continue; } } else { //return ECameraErrorCode.GevSCPSPacketSizeFail; continue; } } apiResult = camera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON); if (nRet != MyCamera.MV_OK) { LogHelper.Debug($"MV_CC_SetIntValue_NET TriggerMode ret = {apiResult}"); //return ECameraErrorCode.SetTriggerModeFail; continue; } apiResult = camera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE); if (nRet != MyCamera.MV_OK) { LogHelper.Debug($"MV_CC_SetIntValue_NET TriggerSource ret = {apiResult}"); //return ECameraErrorCode.SetTriggerSourceFail; continue; } apiResult = camera.MV_CC_RegisterImageCallBackEx_NET(cbImage, (IntPtr)i); if (apiResult != 0) { LogHelper.Debug($"MV_CC_RegisterImageCallBackEx_NET ret = {apiResult}"); continue; //return ECameraErrorCode.RegisterImageCallBackExFail; } CameraInfo ci = new CameraInfo(); ci.Camera = camera; ci.CameraName = cameraInfo; ci.Index = i; cameraInfos.Add(ci); LogHelper.Debug($"Find camera {cameraInfo}"); } } else { //未找到任何相机 return null; } return cameraInfos; } /// /// 根据相机名称获取相机 /// /// /// public CameraInfo GetCameraInfo(string cameraName) { return cameraInfos.Where(c=>c.CameraName==cameraName).FirstOrDefault(); } /// /// 根据索引获取相机 /// /// /// private CameraInfo GetCameraInfo(int index) { return cameraInfos.Where(c => c.Index == index).FirstOrDefault(); } /// /// 获取所有的相机 /// /// public List GetAllCameras() { return cameraInfos; } public void Deinit() { foreach (CameraInfo ci in cameraInfos) { ci.Deinit(); } } } /// /// 相机信息 /// public class CameraInfo { public MyCamera Camera { get; set; } public string CameraName { get; set; } public int Index { get; set; } private List Images; int apiResult = -1; public CameraInfo() { Images = new List(); } public void Deinit() { if(Camera != null) { Camera.MV_CC_CloseDevice_NET(); Camera.MV_CC_DestroyDevice_NET(); } } /// /// 清除内存中的图片 /// public void ClearImage() { lock(this) { if (Images != null) { Images.Clear(); } } } /// /// 取图 /// /// public int Grab() { if (Camera != null) return Camera.MV_CC_SetCommandValue_NET("TriggerSoftware"); return -1; } public int StartGrabbing() { if (Camera != null) return Camera.MV_CC_StartGrabbing_NET(); return -1; } public void AddImage(HObject image) { lock (this) { Images.Add(image); } } /// /// 设置曝光时间 /// /// /// public int SetExposure(float timer) { if (Camera != null) { apiResult = Camera.MV_CC_SetEnumValue_NET("ExposureAuto", 0); if (apiResult != 0) { return apiResult; } apiResult = Camera.MV_CC_SetFloatValue_NET("ExposureTime", timer); if (apiResult != 0) { return apiResult; } } else { return -1; } return 0; } /// /// 设置相机增益 /// /// /// /// public int SetGain(float gain) { if (Camera != null) { apiResult = Camera.MV_CC_SetEnumValue_NET("GainAuto", 0); if (apiResult != 0) { return apiResult; } apiResult = Camera.MV_CC_SetFloatValue_NET("Gain", gain); if (apiResult != 0) { return apiResult; } } else { return -1; } return 0; } /// /// 设置相机的触发模式 /// /// /// /// public int SetTrigger(ETriggerSource triggerSource = ETriggerSource.Line0) { if(Camera!=null) { if (triggerSource == ETriggerSource.Line0) { apiResult = Camera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_LINE0); if (apiResult != 0) { apiResult = Camera.MV_CC_SetEnumValue_NET("TriggerActivation", 0);//设置上升沿触发 if (apiResult != 0) { return apiResult; } } else { return apiResult; } } else { apiResult = Camera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE); if (apiResult != 0) { return apiResult; } } } else { return -1; } return 0; } /// /// 设置相机XY方向是否反转 /// /// /// /// /// public int SetReverse(EDir dir = EDir.X, bool reverse = false) { if(Camera!=null) { if (dir == EDir.X) { apiResult = Camera.MV_CC_SetBoolValue_NET("ReverseX", reverse); if (apiResult != 0) return apiResult; } else { apiResult = Camera.MV_CC_SetBoolValue_NET("ReverseY", reverse); if (apiResult != 0) return apiResult; } } else { return -1; } return 0; } /// /// 获取最后一张图片 /// /// public HObject GetLastImage() { lock (this) { if (Images != null && Images.Count > 0) { return Images[Images.Count - 1]; } return null; } } /// /// 获取所有的图片 /// /// public List GetAllImages() { lock (this) { return Images; } } /// /// 获取图片数量 /// /// public int GetImageCount() { lock (this) { if (Images != null && Images.Count > 0) { return Images.Count; } return 0; } } } }