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