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
}
}