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.Camera { /// /// 方向 /// public enum EDir { X, Y } public enum ECameraErrorCode { Ok, CameraNoExist, EnumDevicesFail, CreateDeviceFail, OpenDeviceFail, GevSCPSPacketSizeFail, SetTriggerModeFail, SetTriggerSourceFail, RegisterImageCallBackExFail, StartGrabbingFail } public enum ETriggerMode { /// /// 手动触发 /// Manual, /// /// 自动触发 /// Auto } public class HikCamera { private static HikCamera instance; public static HikCamera Instance { get { if (instance == null) instance = new HikCamera(); return instance; } } private ETriggerMode m_triggerMode = ETriggerMode.Manual; private HikCamera() { cbImage = new MyCamera.cbOutputExdelegate(ImageCallBack); } MyCamera.MV_CC_DEVICE_INFO_LIST m_pDeviceList; Dictionary cameraDic = new Dictionary(); Dictionary cameraIDs = new Dictionary(); Dictionary camTrigger = new Dictionary(); int apiResult = 0; MyCamera.cbOutputExdelegate cbImage; public event Action AutoGrabOkEvent; public event Action ManualGrabOkEvent; IntPtr m_BufForDriver = IntPtr.Zero; private void ImageCallBack(IntPtr pData, ref MyCamera.MV_FRAME_OUT_INFO_EX pFrameInfo, IntPtr pUser) { HObject image; HOperatorSet.GenEmptyObj(out image); image.Dispose(); int nIndex = (int)pUser; string cameraname = string.Empty; foreach(KeyValuePair kv in cameraIDs) { if(kv.Value== nIndex) { cameraname = kv.Key; break; } } //m_BufForDriver = Marshal.AllocHGlobal((Int32)pFrameInfo.nFrameLen); //CopyMemory(m_BufForDriver, pData, pFrameInfo.nFrameLen); HOperatorSet.GenImage1(out image, "byte", pFrameInfo.nWidth, pFrameInfo.nHeight, pData); //Marshal.FreeHGlobal(pData); //HOperatorSet.RotateImage(image, out HObject rotateImage, 270, "constant"); if (camTrigger!=null && camTrigger.ContainsKey(nIndex)) { if (camTrigger[nIndex] == ETriggerMode.Manual) { //ImageProcess.AddManualTrigger(image); //if (ManualGrabOkEvent != null) { //ManualGrabOkEvent(nIndex, image); ImageProcess.AddManualTrigger(image); } } else if (camTrigger[nIndex] == ETriggerMode.Auto) { ImageProcess.AddAutoTrigger(image); //if (AutoGrabOkEvent != null) //{ // AutoGrabOkEvent(nIndex, image); // ImageProcess.AddAutoTrigger(image); //} } //image.Dispose(); //Marshal.FreeHGlobal(pData); GC.Collect(); } } [DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory", SetLastError = false)] private static extern void CopyMemory(IntPtr dest, IntPtr src, uint count); public List GetCameras() { List list = new List(); foreach (KeyValuePair camera in cameraDic) { list.Add(camera.Key); } return list; } public ECameraErrorCode Init() { int nRet = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref m_pDeviceList); if (nRet != 0) { return ECameraErrorCode.EnumDevicesFail; } else if (m_pDeviceList.nDeviceNum>0) { for (int i = 0; i < m_pDeviceList.nDeviceNum; i++) { ///获取相机信息 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)); string cameraInfo = gigeInfo.chUserDefinedName;// gigeInfo.chModelName + " (" + gigeInfo.chSerialNumber + ")"; MyCamera camera = new MyCamera(); cameraDic.Add(cameraInfo, camera); apiResult = camera.MV_CC_CreateDevice_NET(ref device); if (apiResult != 0) { return ECameraErrorCode.CreateDeviceFail; } apiResult = camera.MV_CC_OpenDevice_NET(); if (apiResult != 0) { return ECameraErrorCode.OpenDeviceFail; } 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) { return ECameraErrorCode.GevSCPSPacketSizeFail; } } else { return ECameraErrorCode.GevSCPSPacketSizeFail; } } apiResult = camera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON); if (nRet != MyCamera.MV_OK) { return ECameraErrorCode.SetTriggerModeFail; } apiResult = camera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE); if (nRet != MyCamera.MV_OK) { return ECameraErrorCode.SetTriggerSourceFail; } apiResult = camera.MV_CC_RegisterImageCallBackEx_NET(cbImage, (IntPtr)i); if (apiResult != 0) { return ECameraErrorCode.RegisterImageCallBackExFail; } cameraIDs.Add(cameraInfo, i); camTrigger.Add(i, ETriggerMode.Manual); //apiResult = camera.MV_CC_StartGrabbing_NET(); if(apiResult!=0) { return ECameraErrorCode.StartGrabbingFail; } } 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)); string cameraInfo = usbInfo.chUserDefinedName;// gigeInfo.chModelName + " (" + gigeInfo.chSerialNumber + ")"; if (string.IsNullOrEmpty(cameraInfo)) continue; MyCamera camera = new MyCamera(); cameraDic.Add(cameraInfo, camera); apiResult = camera.MV_CC_CreateDevice_NET(ref device); if (apiResult != 0) { return ECameraErrorCode.CreateDeviceFail; } apiResult = camera.MV_CC_OpenDevice_NET(); if (apiResult != 0) { return ECameraErrorCode.OpenDeviceFail; } apiResult = camera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON); if (nRet != MyCamera.MV_OK) { return ECameraErrorCode.SetTriggerModeFail; } apiResult = camera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE); if (nRet != MyCamera.MV_OK) { return ECameraErrorCode.SetTriggerSourceFail; } apiResult = camera.MV_CC_RegisterImageCallBackEx_NET(cbImage, (IntPtr)i); if (apiResult != 0) { return ECameraErrorCode.RegisterImageCallBackExFail; } cameraIDs.Add(cameraInfo, i); camTrigger.Add(i, ETriggerMode.Manual); //apiResult = camera.MV_CC_StartGrabbing_NET(); if (apiResult != 0) { return ECameraErrorCode.StartGrabbingFail; } } } } else { return ECameraErrorCode.CameraNoExist; } return ECameraErrorCode.Ok; } public int Grab(string camName) { if(cameraDic.ContainsKey(camName)) { apiResult = cameraDic[camName].MV_CC_SetCommandValue_NET("TriggerSoftware"); if(apiResult==0) { return 0; } } return -1; } public ECameraErrorCode Deinit() { foreach (KeyValuePair item in cameraDic) { item.Value.MV_CC_CloseDevice_NET(); item.Value.MV_CC_DestroyDevice_NET(); } return ECameraErrorCode.Ok; } public int SetExposure(string camName,float timer) { if (cameraDic.ContainsKey(camName)) { apiResult = cameraDic[camName].MV_CC_SetEnumValue_NET("ExposureAuto", 0); if (apiResult != 0) { return -1; } apiResult = cameraDic[camName].MV_CC_SetFloatValue_NET("ExposureTime", timer); if (apiResult != 0) { return -1; } } return 0; } public int SetGain(string camName, float gain) { if (cameraDic.ContainsKey(camName)) { apiResult = cameraDic[camName].MV_CC_SetEnumValue_NET("GainAuto", 0); if (apiResult != 0) { return -1; } apiResult = cameraDic[camName].MV_CC_SetFloatValue_NET("Gain", gain); if (apiResult != 0) { return -1; } } return 0; } public int SetTrigger(string camName, ETriggerMode triggerMode= ETriggerMode.Manual) { if (cameraDic.ContainsKey(camName)) { if (!camTrigger.ContainsKey(cameraIDs[camName])) { return -1; } camTrigger[cameraIDs[camName]] = triggerMode; if (triggerMode== ETriggerMode.Auto) { apiResult = cameraDic[camName].MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_LINE0); if (apiResult != 0) { return -1; } apiResult = cameraDic[camName].MV_CC_SetEnumValue_NET("TriggerActivation", 0);//设置上升沿触发 if (apiResult != 0) { return -1; } } else { //apiResult = cameraDic[camName].MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE); apiResult = cameraDic[camName].MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_LINE0); if (apiResult != 0) { return -1; } apiResult = cameraDic[camName].MV_CC_SetEnumValue_NET("TriggerActivation", 0);//设置上升沿触发 if (apiResult != 0) { return -1; } } } return 0; } public int SetReverseX(string camName,EDir dir= EDir.X,bool reverse=false) { if (cameraDic.ContainsKey(camName)) { if(dir== EDir.X) { apiResult = cameraDic[camName].MV_CC_SetBoolValue_NET("ReverseX", reverse); } else { apiResult = cameraDic[camName].MV_CC_SetBoolValue_NET("ReverseY", reverse); } if (apiResult != 0) { return -1; } } return 0; } public int StartGrab(string camName) { if (cameraDic.ContainsKey(camName)) { apiResult = cameraDic[camName].MV_CC_StartGrabbing_NET(); if (apiResult != 0) { return -1; } } return 0; } } }