using Cognex.VisionPro; using MaterialDesignThemes.Wpf; using Microsoft.Win32; using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.Contracts; using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; using TeamAAS_VP.Enums; using TeamAAS_VP.Interfaces; using TeamAAS_VP.Models; using TeamAAS_VP; namespace TeamAAS_VP.Core.Cameras { public class CognexCamera : CameraBase, ICamera, INotifyPropertyChanged { #region 字段 private Thread m_hReceiveThread; #endregion #region 属性 public CameraBrand CameraBrand { get => CameraBrand.Cognex; } public string Name { get; private set; } public Guid ID { get; private set; } public int Index { get; set; } public string ManufacturerName { get; private set; } public bool IsFindByIp { get; private set; } public string ModelName { get; private set; } public string SerialNumber { get; private set; } public string CameraIp { get; private set; } public CameraType CameraType { get; private set; } ICogAcqFifo CameraAcq; public UInt32 ImageWidth { get; private set; } public UInt32 ImageHeight { 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; } /// /// 采集用时 /// public TimeSpan TotalTime { get; private set; } /// /// 错误信息 /// public string ErrorMessage { get; private set; } private bool IsHaveCamera = false; #endregion #region 事件 public event Action ImageCallbackEvent; public event Action CameraConnectChangedEvent; #endregion public CognexCamera(Guid id, int index, string name, string serialNumber, string cameraip, bool isFindByIp) { ID = id; Name = serialNumber; Index = index; CameraIp = cameraip; SerialNumber = serialNumber; IsFindByIp = isFindByIp; //using (CogFrameGrabbers mFrameGrabbers = new CogFrameGrabbers())//识别已安装的帧抓取器的类//帧抓取器:相机 //{ // foreach (ICogFrameGrabber item in mFrameGrabbers) // { // if (item.SerialNumber == SerialNumber) // { // var videoFormat = item.AvailableVideoFormats[0]; // foreach (string format in item.AvailableVideoFormats) // { // if (format == "Generic GigEVision (Mono)") // { // videoFormat = format; // break; // } // if (format != "Generic GigEVision (Bayer Color)") continue; // videoFormat = format; // break; // } // CameraAcq = item.CreateAcqFifo(videoFormat, CogAcqFifoPixelFormatConstants.Format8Grey, 0, // true); // //CameraAcq.OwnedExposureParams.Exposure = exposure; // //CameraAcq.OwnedBrightnessParams.Brightness = brightness; // //CameraAcq.OwnedContrastParams.Contrast = contrast; // // // CameraAcq.OwnedTriggerParams.TriggerEnabled = true; // CameraAcq.OwnedTriggerParams.TriggerModel = CogAcqTriggerModelConstants.FreeRun; // IsHaveCamera = true; // break; // } // } //} IsConnected = false; } #region 方法 /// /// 获取设备 /// /// public static CameraInfo[] GetDevices() { List cameras = new List(); if (!CheckSoftwareInstalled().isInstalled) { LogHelper.WriteLogInfo("未安装Cognex VisionPro"); return cameras.ToArray(); } using (CogFrameGrabbers mFrameGrabbers = new CogFrameGrabbers())//识别已安装的帧抓取器的类//帧抓取器:相机 { int i = 0; foreach (ICogFrameGrabber item in mFrameGrabbers) { string[] bf1 = item.Name.Split(':'); string manufacturerName = item.Name; string model = item.Name; CameraType type = CameraType.GIGE; if (bf1.Length == 3) { manufacturerName = bf1[1].Trim(); model = bf1[2].Trim(); if (bf1[0].ToLower().Trim().Contains("gige")) { type = CameraType.GIGE; } else if (bf1[0].ToLower().Trim().Contains("usb")) { type = CameraType.USB; } else { type = CameraType.Unknown; } } if (type == CameraType.GIGE) { cameras.Add(new Models.CameraInfo() { CameraNo = i + 1, CameraName = item.Name, CameraBrand = CameraBrand.Cognex, CameraType = type, ManufacturerName = manufacturerName, Model = model, SerialNumber = item.SerialNumber, CameraIp = item.OwnedGigEAccess.CurrentIPAddress, IsFindByIp = true, }); } else { cameras.Add(new Models.CameraInfo() { CameraNo = i + 1, CameraName = "", CameraBrand = CameraBrand.Cognex, CameraType = type, ManufacturerName = manufacturerName, Model = model, SerialNumber = item.SerialNumber, CameraIp = item.Name, }); } i++; } } return cameras.ToArray(); } /// /// 检查相机软件是否安装 /// /// public static (bool isInstalled, string version) CheckSoftwareInstalled() { string softwareName = "Cognex VisionPro"; string softwareVersion = "90.0.5"; string[] registryPaths = new[] { @"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", @"SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall" }; foreach (var path in registryPaths) { using (RegistryKey key = Registry.LocalMachine.OpenSubKey(path)) { if (key == null) continue; foreach (string subKeyName in key.GetSubKeyNames()) { using (RegistryKey subKey = key.OpenSubKey(subKeyName)) { string displayName = subKey.GetValue("DisplayName")?.ToString(); if (displayName != null && displayName.Contains(softwareName)) { string version = subKey.GetValue("DisplayVersion")?.ToString(); Version v1 = new Version(version); Version v2 = new Version(softwareVersion); if (v1 >= v2) { return (true, version); } else { return (false, version); } } } } } } return (false, ""); } /// /// 打开相机 /// /// /// public bool OpenDevice() { EnterOperation(); try { IsConnected = false; if (!IsHaveCamera || CameraAcq == null) { using (CogFrameGrabbers mFrameGrabbers = new CogFrameGrabbers())//识别已安装的帧抓取器的类//帧抓取器:相机 { foreach (ICogFrameGrabber item in mFrameGrabbers) { string[] bf1 = item.Name.Split(':'); CameraType type = CameraType.GIGE; if (bf1.Length == 3) { if (bf1[0].ToLower().Trim().Contains("gige")) { type = CameraType.GIGE; } else if (bf1[0].ToLower().Trim().Contains("usb")) { type = CameraType.USB; } else { type = CameraType.Unknown; } } if (type == CameraType.GIGE) { if (IsFindByIp) { if (CameraIp == item.OwnedGigEAccess.CurrentIPAddress) { var videoFormat = item.AvailableVideoFormats[0]; foreach (string format in item.AvailableVideoFormats) { if (format == "Generic GigEVision (Mono)") { videoFormat = format; break; } if (format != "Generic GigEVision (Bayer Color)") continue; videoFormat = format; break; } CameraAcq = item.CreateAcqFifo(videoFormat, CogAcqFifoPixelFormatConstants.Format8Grey, 0, true); //CameraAcq.OwnedExposureParams.Exposure = exposure; //CameraAcq.OwnedBrightnessParams.Brightness = brightness; //CameraAcq.OwnedContrastParams.Contrast = contrast; // CameraAcq.OwnedTriggerParams.TriggerEnabled = true; CameraAcq.OwnedTriggerParams.TriggerModel = CogAcqTriggerModelConstants.FreeRun; string manufacturerName = item.Name; string model = item.Name; manufacturerName = bf1[1].Trim(); model = bf1[2].Trim(); ManufacturerName = manufacturerName; ModelName = model; CameraIp = item.OwnedGigEAccess.CurrentIPAddress; IsHaveCamera = true; break; } } else { if (item.SerialNumber == SerialNumber) { var videoFormat = item.AvailableVideoFormats[0]; foreach (string format in item.AvailableVideoFormats) { if (format == "Generic GigEVision (Mono)") { videoFormat = format; break; } if (format != "Generic GigEVision (Bayer Color)") continue; videoFormat = format; break; } CameraAcq = item.CreateAcqFifo(videoFormat, CogAcqFifoPixelFormatConstants.Format8Grey, 0, true); //CameraAcq.OwnedExposureParams.Exposure = exposure; //CameraAcq.OwnedBrightnessParams.Brightness = brightness; //CameraAcq.OwnedContrastParams.Contrast = contrast; // CameraAcq.OwnedTriggerParams.TriggerEnabled = true; CameraAcq.OwnedTriggerParams.TriggerModel = CogAcqTriggerModelConstants.FreeRun; string manufacturerName = item.Name; string model = item.Name; manufacturerName = bf1[1].Trim(); model = bf1[2].Trim(); ManufacturerName = manufacturerName; ModelName = model; CameraIp = item.OwnedGigEAccess.CurrentIPAddress; IsHaveCamera = true; break; } } } else { if (item.SerialNumber == SerialNumber) { var videoFormat = item.AvailableVideoFormats[0]; foreach (string format in item.AvailableVideoFormats) { if (format == "Generic GigEVision (Mono)") { videoFormat = format; break; } if (format != "Generic GigEVision (Bayer Color)") continue; videoFormat = format; break; } CameraAcq = item.CreateAcqFifo(videoFormat, CogAcqFifoPixelFormatConstants.Format8Grey, 0, true); //CameraAcq.OwnedExposureParams.Exposure = exposure; //CameraAcq.OwnedBrightnessParams.Brightness = brightness; //CameraAcq.OwnedContrastParams.Contrast = contrast; // CameraAcq.OwnedTriggerParams.TriggerEnabled = true; CameraAcq.OwnedTriggerParams.TriggerModel = CogAcqTriggerModelConstants.FreeRun; string manufacturerName = item.Name; string model = item.Name; manufacturerName = bf1[1].Trim(); model = bf1[2].Trim(); ManufacturerName = manufacturerName; ModelName = model; IsHaveCamera = true; break; } } } } if (!IsHaveCamera) { return false; } } if (!IsConnected) { CameraConnectChangedEvent?.Invoke(ID, true); } IsConnected = true; return IsConnected; } finally { ExitOperation(); } } /// /// 打开相机异步 /// /// public Task OpenDeviceAsync() { return Task.Run(() => { return OpenDevice(); }); } /// /// 关闭相机 /// public void CloseDevice() { EnterOperation(); try { if (CameraAcq != null) { CameraAcq = null; } IsConnected = false; } finally { ExitOperation(); } } /// /// 采集单张图片 /// /// true:采集一张新图像,false:返回最后一张图像 /// public ICogImage Grab(bool lastImageOnly = true) { EnterOperation(); try { Stopwatch sw = Stopwatch.StartNew(); for (int i = 0; i < 5; i++) { try { if (CameraAcq == null) { OpenDevice(); } CameraAcq.Flush(); Image = CameraAcq.CompleteAcquireEx(new CogAcqInfo()); ImageWidth = (uint)Image.Width; ImageHeight = (uint)Image.Height; TotalTime = sw.Elapsed; ErrorMessage = ""; return Image; } catch (Exception ex) { ErrorMessage = ex.Message; CloseDevice(); Thread.Sleep(100); OpenDevice(); } } if (IsConnected) { IsConnected = false; CameraConnectChangedEvent?.Invoke(ID, false); } return null; } finally { ExitOperation(); } } /// /// 开始采集图像 /// public void StartGrabbing() { lock (_stateLock) { if (IsGrabbing) return; IsGrabbing = true; } m_hReceiveThread = new Thread(GetStreamThreadProc) { IsBackground = true }; m_hReceiveThread.Start(); } /// /// 停止采集图像 /// public void StopGrabbing() { try { lock (_stateLock) { IsGrabbing = false; } Thread.Sleep(1000); if (m_hReceiveThread != null) { m_hReceiveThread.Abort(); m_hReceiveThread = null; } } catch (Exception) { } } /// /// 设置曝光时间 /// /// /// public bool SetExposureTime(float ExposureTime) { EnterOperation(); try { if (CameraAcq == null) return false; CameraAcq.OwnedExposureParams.Exposure = (double)ExposureTime; return true; } finally { ExitOperation(); } } /// /// 获取曝光时间 /// /// public float GetExposureTime() { EnterOperation(); try { if (CameraAcq == null) return 0; return (float)CameraAcq.OwnedExposureParams.Exposure; } finally { ExitOperation(); } } /// /// 设置增益 /// /// /// public bool SetGain(float Gain) { EnterOperation(); try { if (CameraAcq == null) return false; // 设置增益 CameraAcq.OwnedBrightnessParams.Brightness = (double)Gain; return true; } finally { ExitOperation(); } } /// /// 获取增益 /// /// public float GetGain() { EnterOperation(); try { if (CameraAcq == null) return 0; return (float)(CameraAcq.OwnedBrightnessParams.Brightness); } finally { ExitOperation(); } } 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. 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); } #endregion } }