using Cognex.VisionPro; using MvCamCtrl.NET; using SqlSugar.DistributedSystem.Snowflake; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Data.SqlTypes; using System.Diagnostics; using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; using static MvCamCtrl.NET.MyCamera; namespace LampInspectionMachine.Cameralibs.HKCamera { public class MvCamera : ICamera, INotifyPropertyChanged { #region 字段 private Thread m_hReceiveThread; #endregion #region 属性 public CameraBrand CameraBrand { get => CameraBrand.HikRobot_MVS; } public string Name { get; private set; } public Guid ID { get; private set; } public string ManufacturerName { get; private set; } public string ModelName { get; private set; } public string SerialNumber { get; private set; } public CameraType CameraType { get; private set; } MvCameraAcqTool.MvCameraAcqTool mvCameraAcq; public MyCamera.MV_CC_DEVICE_INFO CameraInfo { get; private set; } public UInt32 ImageWidth { get; private set; } public UInt32 ImageHeight { get; private set; } public MvCamCtrl.NET.MvGvspPixelType PixelType { get; private set; } private bool _IsGrabbing; /// /// 正在采集 /// public bool IsGrabbing { get { return _IsGrabbing; } private set { SetProperty(ref _IsGrabbing, value); } } private ICogImage _Image; public ICogImage Image { get { return _Image; } private set { SetProperty(ref _Image, value); } } public bool IsConnected { get; private set; } private bool IsHaveCamera = false; /// /// 采集用时 /// public TimeSpan TotalTime { get; private set; } /// /// 错误信息 /// public string ErrorMessage { get; private set; } #endregion #region 事件 public event Action ImageCallbackEvent; public event Action CameraConnectChangedEvent; #endregion public MvCamera(Guid _ID, string _SerialNumber) { ID = _ID; SerialNumber = _SerialNumber; mvCameraAcq = new MvCameraAcqTool.MvCameraAcqTool(); MyCamera.MV_CC_DEVICE_INFO_LIST stDeviceList = default(MyCamera.MV_CC_DEVICE_INFO_LIST); mvCameraAcq.EnumDeivce(ref stDeviceList); MyCamera.MV_CC_DEVICE_INFO device = default(MyCamera.MV_CC_DEVICE_INFO); for ( int i = 0; i < stDeviceList.nDeviceNum; i++ ) { device = ( MyCamera.MV_CC_DEVICE_INFO ) Marshal.PtrToStructure(stDeviceList.pDeviceInfo[ i ], typeof(MyCamera.MV_CC_DEVICE_INFO)); if ( device.nTLayerType == CSystem.MV_GIGE_DEVICE ) { MV_GIGE_DEVICE_INFO stGigEDeviceInfo = (MV_GIGE_DEVICE_INFO)MyCamera.ByteToStruct(device.SpecialInfo.stGigEInfo, typeof(MV_GIGE_DEVICE_INFO)); if ( string.Equals(stGigEDeviceInfo.chSerialNumber, _SerialNumber) ) { ManufacturerName = stGigEDeviceInfo.chManufacturerName; ModelName = stGigEDeviceInfo.chModelName; SerialNumber = stGigEDeviceInfo.chSerialNumber; CameraType = CameraType.GIGE; CameraInfo = device; IsHaveCamera = true; break; } } else if ( device.nTLayerType == CSystem.MV_USB_DEVICE ) { MV_USB3_DEVICE_INFO usbInfo = (MV_USB3_DEVICE_INFO)MyCamera.ByteToStruct(device.SpecialInfo.stUsb3VInfo, typeof(MV_USB3_DEVICE_INFO)); if ( string.Equals(usbInfo.chSerialNumber, _SerialNumber) ) { ManufacturerName = usbInfo.chManufacturerName; ModelName = usbInfo.chModelName; SerialNumber = usbInfo.chSerialNumber; CameraType = CameraType.USB; CameraInfo = device; IsHaveCamera = true; break; } } } IsConnected = false; } #region 方法 public List GetListEnum() { GC.Collect(); mvCameraAcq = new MvCameraAcqTool.MvCameraAcqTool(); MyCamera.MV_CC_DEVICE_INFO_LIST stDeviceList = default(MyCamera.MV_CC_DEVICE_INFO_LIST); mvCameraAcq.EnumDeivce(ref stDeviceList); List listsn = new List(); MyCamera.MV_CC_DEVICE_INFO device = default(MyCamera.MV_CC_DEVICE_INFO); for ( int i = 0; i < stDeviceList.nDeviceNum; i++ ) { device = ( MyCamera.MV_CC_DEVICE_INFO ) Marshal.PtrToStructure(stDeviceList.pDeviceInfo[ i ], typeof(MyCamera.MV_CC_DEVICE_INFO)); if ( device.nTLayerType == CSystem.MV_GIGE_DEVICE ) { MV_GIGE_DEVICE_INFO stGigEDeviceInfo = (MV_GIGE_DEVICE_INFO)MyCamera.ByteToStruct(device.SpecialInfo.stGigEInfo, typeof(MV_GIGE_DEVICE_INFO)); listsn.Add(stGigEDeviceInfo.chSerialNumber); } else if ( device.nTLayerType == CSystem.MV_USB_DEVICE ) { MV_USB3_DEVICE_INFO usbInfo = (MV_USB3_DEVICE_INFO)MyCamera.ByteToStruct(device.SpecialInfo.stUsb3VInfo, typeof(MV_USB3_DEVICE_INFO)); listsn.Add(usbInfo.chSerialNumber); } } return listsn; } /// /// 打开相机 /// /// /// public bool OpenDevice() { if ( !IsHaveCamera ) { mvCameraAcq = new MvCameraAcqTool.MvCameraAcqTool(); MyCamera.MV_CC_DEVICE_INFO_LIST stDeviceList = default(MyCamera.MV_CC_DEVICE_INFO_LIST); mvCameraAcq.EnumDeivce(ref stDeviceList); MyCamera.MV_CC_DEVICE_INFO device = default(MyCamera.MV_CC_DEVICE_INFO); for ( int i = 0; i < stDeviceList.nDeviceNum; i++ ) { device = ( MyCamera.MV_CC_DEVICE_INFO ) Marshal.PtrToStructure(stDeviceList.pDeviceInfo[ i ], typeof(MyCamera.MV_CC_DEVICE_INFO)); if ( device.nTLayerType == CSystem.MV_GIGE_DEVICE ) { MV_GIGE_DEVICE_INFO stGigEDeviceInfo = (MV_GIGE_DEVICE_INFO)MyCamera.ByteToStruct(device.SpecialInfo.stGigEInfo, typeof(MV_GIGE_DEVICE_INFO)); if ( string.Equals(stGigEDeviceInfo.chSerialNumber, SerialNumber) ) { ManufacturerName = stGigEDeviceInfo.chManufacturerName; ModelName = stGigEDeviceInfo.chModelName; SerialNumber = stGigEDeviceInfo.chSerialNumber; CameraType = CameraType.GIGE; CameraInfo = device; IsHaveCamera = true; break; } } else if ( device.nTLayerType == CSystem.MV_USB_DEVICE ) { MV_USB3_DEVICE_INFO usbInfo = (MV_USB3_DEVICE_INFO)MyCamera.ByteToStruct(device.SpecialInfo.stUsb3VInfo, typeof(MV_USB3_DEVICE_INFO)); if ( string.Equals(usbInfo.chSerialNumber, SerialNumber) ) { ManufacturerName = usbInfo.chManufacturerName; ModelName = usbInfo.chModelName; SerialNumber = usbInfo.chSerialNumber; CameraType = CameraType.USB; CameraInfo = device; IsHaveCamera = true; break; } } } if ( !IsHaveCamera ) { throw new Exception("没有发现相机"); } } mvCameraAcq.OpenDevice(CameraInfo); mvCameraAcq.AutoExposure = false; mvCameraAcq.TriggerMode = false; if ( !IsConnected ) { CameraConnectChangedEvent?.Invoke(ID, true); } IsConnected = mvCameraAcq.bIsOpened; return IsConnected; } /// /// 关闭相机 /// public void CloseDevice() { // ch:关闭设备 | en:Close Device mvCameraAcq.CloseDevice(); } public void SetTriggerModeOn() { mvCameraAcq.TriggerMode = true; } public void SetTriggerModeOff() { mvCameraAcq.TriggerMode = false; } public void SetTriggerSoftware(int value = 7) { // 设置触发源为Line0 mvCameraAcq.TriggerSoftware =value ; CCamera.RegisterImageCallBackEx(, IntPtr.Zero); } /// /// 采集图像 /// /// public ICogImage Grab() { Stopwatch sw = Stopwatch.StartNew(); for ( int i = 0; i < 5; i++ ) { try { if ( !mvCameraAcq.bIsOpened ) { OpenDevice(); } mvCameraAcq.Run(); if ( mvCameraAcq.RunStatus.Result == CogToolResultConstants.Accept ) { ErrorMessage = ""; Image = mvCameraAcq.OutputImage; if ( !IsConnected ) { IsConnected = true; CameraConnectChangedEvent?.Invoke(ID, true); } TotalTime = sw.Elapsed; ImageCallbackEvent?.Invoke(Image, TotalTime, ErrorMessage); return Image; } else { ErrorMessage = mvCameraAcq.RunStatus.Message; CloseDevice(); OpenDevice(); } } catch ( Exception ex ) { CloseDevice(); OpenDevice(); ErrorMessage = ex.Message; } } if ( IsConnected ) { IsConnected = false; CameraConnectChangedEvent?.Invoke(ID, false); } return null; } /// /// 开始采集图像 /// public void StartGrabbing() { if ( IsGrabbing ) return; IsGrabbing = true; m_hReceiveThread = new Thread(GetStreamThreadProc) { IsBackground = true }; m_hReceiveThread.Start(); } /// /// 停止采集图像 /// public void StopGrabbing() { try { if ( IsGrabbing ) { IsGrabbing = false; Thread.Sleep(1000); if ( m_hReceiveThread != null ) { m_hReceiveThread.Abort(); m_hReceiveThread = null; } } } catch ( Exception ) { } } /// /// 设置曝光时间 /// /// /// public bool SetExposureTime(float ExposureTime) { if ( !mvCameraAcq.bIsOpened ) return false; mvCameraAcq.ExposureTime = ( double ) ExposureTime; return true; } /// /// 获取曝光时间 /// /// public float GetExposureTime() { if ( !mvCameraAcq.bIsOpened ) return 0; return ( float ) mvCameraAcq.ExposureTime; } /// /// 设置增益 /// /// /// public bool SetGain(float Gain) { if ( !mvCameraAcq.bIsOpened ) return false; mvCameraAcq.AnalogGain = ( double ) Gain; return true; } /// /// 获取增益 /// /// public float GetGain() { if ( !mvCameraAcq.bIsOpened ) return 0; return ( float ) mvCameraAcq.AnalogGain; } private void GetStreamThreadProc() { while ( IsGrabbing ) { try { Grab(); ImageCallbackEvent?.Invoke(Image, TotalTime, ErrorMessage); } catch ( Exception ) { } Thread.Sleep(10); } IsGrabbing = false; } #endregion #region 属性通知 /// /// Occurs when a property value changes. /// public event PropertyChangedEventHandler PropertyChanged; /// /// Checks if a property already matches a desired value. Sets the property and /// notifies listeners only when necessary. /// /// Type of the property. /// Reference to a property with both getter and setter. /// Desired value for the property. /// Name of the property used to notify listeners. This /// value is optional and can be provided automatically when invoked from compilers that /// support CallerMemberName. /// True if the value was changed, false if the existing value matched the /// desired value. protected virtual bool SetProperty(ref T storage, T value, [CallerMemberName] string propertyName = null) { if ( EqualityComparer.Default.Equals(storage, value) ) return false; storage = value; RaisePropertyChanged(propertyName); return true; } /// /// Checks if a property already matches a desired value. Sets the property and /// notifies listeners only when necessary. /// /// Type of the property. /// Reference to a property with both getter and setter. /// Desired value for the property. /// Name of the property used to notify listeners. This /// value is optional and can be provided automatically when invoked from compilers that /// support CallerMemberName. /// Action that is called after the property value has been changed. /// True if the value was changed, false if the existing value matched the /// desired value. protected virtual bool SetProperty(ref T storage, T value, Action onChanged, [CallerMemberName] string propertyName = null) { if ( EqualityComparer.Default.Equals(storage, value) ) return false; storage = value; onChanged?.Invoke(); RaisePropertyChanged(propertyName); return true; } /// /// Raises this object's PropertyChanged event. /// /// Name of the property used to notify listeners. This /// value is optional and can be provided automatically when invoked from compilers /// that support . protected void RaisePropertyChanged([CallerMemberName] string propertyName = null) { OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); } /// /// Raises this object's PropertyChanged event. /// /// The PropertyChangedEventArgs protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) { PropertyChanged?.Invoke(this, args); } public bool CheckImageCallbackEvent(Action CamCallBack) { if ( ImageCallbackEvent==null||!ImageCallbackEvent.GetInvocationList().Contains(CamCallBack) ) { return true; } return false; } #endregion } }