|
|
@@ -1,710 +1,711 @@
|
|
|
-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 : CameraBaseLock, 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;
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 正在采集
|
|
|
- /// </summary>
|
|
|
- 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; }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 采集用时
|
|
|
- /// </summary>
|
|
|
- public TimeSpan TotalTime { get; private set; }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 错误信息
|
|
|
- /// </summary>
|
|
|
- public string ErrorMessage { get; private set; }
|
|
|
-
|
|
|
- private bool IsHaveCamera = false;
|
|
|
- #endregion
|
|
|
-
|
|
|
- #region 事件
|
|
|
- public event Action<ICogImage, TimeSpan, string> ImageCallbackEvent;
|
|
|
- public event Action<Guid, bool> 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 方法
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 获取设备
|
|
|
- /// </summary>
|
|
|
- /// <returns></returns>
|
|
|
- public static CameraInfo[] GetDevices()
|
|
|
- {
|
|
|
- List<CameraInfo> cameras = new List<CameraInfo>();
|
|
|
- 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();
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 检查相机软件是否安装
|
|
|
- /// </summary>
|
|
|
- /// <returns></returns>
|
|
|
- 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, "");
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 打开相机
|
|
|
- /// </summary>
|
|
|
- /// <returns></returns>
|
|
|
- /// <exception cref="Exception"></exception>
|
|
|
- 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();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 打开相机异步
|
|
|
- /// </summary>
|
|
|
- /// <returns></returns>
|
|
|
- public Task<bool> OpenDeviceAsync()
|
|
|
- {
|
|
|
- return Task.Run(() =>
|
|
|
- {
|
|
|
- return OpenDevice();
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 关闭相机
|
|
|
- /// </summary>
|
|
|
- public void CloseDevice()
|
|
|
- {
|
|
|
- EnterOperation();
|
|
|
- try
|
|
|
- {
|
|
|
- if (CameraAcq!=null)
|
|
|
- {
|
|
|
- CameraAcq = null;
|
|
|
-
|
|
|
- }
|
|
|
- IsConnected = false;
|
|
|
- }
|
|
|
- finally
|
|
|
- {
|
|
|
- ExitOperation();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 采集图像
|
|
|
- /// </summary>
|
|
|
- /// <returns></returns>
|
|
|
- public ICogImage Grab()
|
|
|
- {
|
|
|
- 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();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 开始采集图像
|
|
|
- /// </summary>
|
|
|
- public void StartGrabbing()
|
|
|
- {
|
|
|
- lock (_stateLock)
|
|
|
- {
|
|
|
- if (IsGrabbing)
|
|
|
- return;
|
|
|
- IsGrabbing = true;
|
|
|
- }
|
|
|
- m_hReceiveThread = new Thread(GetStreamThreadProc) { IsBackground = true };
|
|
|
- m_hReceiveThread.Start();
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 停止采集图像
|
|
|
- /// </summary>
|
|
|
- public void StopGrabbing()
|
|
|
- {
|
|
|
- try
|
|
|
- {
|
|
|
- lock (_stateLock)
|
|
|
- {
|
|
|
- IsGrabbing = false;
|
|
|
- }
|
|
|
- Thread.Sleep(1000);
|
|
|
- if (m_hReceiveThread != null)
|
|
|
- {
|
|
|
- m_hReceiveThread.Abort();
|
|
|
- m_hReceiveThread = null;
|
|
|
- }
|
|
|
- }
|
|
|
- catch (Exception)
|
|
|
- {
|
|
|
-
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 设置曝光时间
|
|
|
- /// </summary>
|
|
|
- /// <param name="ExposureTime"></param>
|
|
|
- /// <returns></returns>
|
|
|
- public bool SetExposureTime(float ExposureTime)
|
|
|
- {
|
|
|
- EnterOperation();
|
|
|
- try
|
|
|
- {
|
|
|
- if (CameraAcq==null)
|
|
|
- return false;
|
|
|
- CameraAcq.OwnedExposureParams.Exposure = (double)ExposureTime;
|
|
|
- return true;
|
|
|
- }
|
|
|
- finally
|
|
|
- {
|
|
|
- ExitOperation();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 获取曝光时间
|
|
|
- /// </summary>
|
|
|
- /// <returns></returns>
|
|
|
- public float GetExposureTime()
|
|
|
- {
|
|
|
- EnterOperation();
|
|
|
- try
|
|
|
- {
|
|
|
- if (CameraAcq == null)
|
|
|
- return 0;
|
|
|
- return (float)CameraAcq.OwnedExposureParams.Exposure;
|
|
|
- }
|
|
|
- finally
|
|
|
- {
|
|
|
- ExitOperation();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 设置增益
|
|
|
- /// </summary>
|
|
|
- /// <param name="Gain"></param>
|
|
|
- /// <returns></returns>
|
|
|
- public bool SetGain(float Gain)
|
|
|
- {
|
|
|
- EnterOperation();
|
|
|
- try
|
|
|
- {
|
|
|
- if (CameraAcq==null)
|
|
|
- return false;
|
|
|
- // 设置增益
|
|
|
- CameraAcq.OwnedBrightnessParams.Brightness = (double)Gain;
|
|
|
- return true;
|
|
|
- }
|
|
|
- finally
|
|
|
- {
|
|
|
- ExitOperation();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 获取增益
|
|
|
- /// </summary>
|
|
|
- /// <returns></returns>
|
|
|
- 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 属性通知
|
|
|
- /// <summary>
|
|
|
- /// Occurs when a property value changes.
|
|
|
- /// </summary>
|
|
|
- public event PropertyChangedEventHandler PropertyChanged;
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// Checks if a property already matches a desired value. Sets the property and
|
|
|
- /// notifies listeners only when necessary.
protected virtual bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
|
|
|
- {
|
|
|
- if (EqualityComparer<T>.Default.Equals(storage, value)) return false;
|
|
|
-
|
|
|
- storage = value;
|
|
|
- RaisePropertyChanged(propertyName);
|
|
|
-
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// Checks if a property already matches a desired value. Sets the property and
|
|
|
- /// notifies listeners only when necessary.
|
|
|
- /// </summary>
|
|
|
- /// <typeparam name="T">Type of the property.</typeparam>
|
|
|
- /// <param name="storage">Reference to a property with both getter and setter.</param>
|
|
|
- /// <param name="value">Desired value for the property.</param>
|
|
|
- /// <param name="propertyName">Name of the property used to notify listeners. This
|
|
|
- /// value is optional and can be provided automatically when invoked from compilers that
|
|
|
- /// support CallerMemberName.</param>
|
|
|
- /// <param name="onChanged">Action that is called after the property value has been changed.</param>
|
|
|
- /// <returns>True if the value was changed, false if the existing value matched the
|
|
|
- /// desired value.</returns>
|
|
|
- protected virtual bool SetProperty<T>(ref T storage, T value, Action onChanged, [CallerMemberName] string propertyName = null)
|
|
|
- {
|
|
|
- if (EqualityComparer<T>.Default.Equals(storage, value)) return false;
|
|
|
-
|
|
|
- storage = value;
|
|
|
- onChanged?.Invoke();
|
|
|
- RaisePropertyChanged(propertyName);
|
|
|
-
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// Raises this object's PropertyChanged event.
|
|
|
- /// </summary>
|
|
|
- /// <param name="propertyName">Name of the property used to notify listeners. This
|
|
|
- /// value is optional and can be provided automatically when invoked from compilers
|
|
|
- /// that support <see cref="CallerMemberNameAttribute"/>.</param>
|
|
|
- protected void RaisePropertyChanged([CallerMemberName] string propertyName = null)
|
|
|
- {
|
|
|
- OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// Raises this object's PropertyChanged event.
|
|
|
- /// </summary>
|
|
|
- /// <param name="args">The PropertyChangedEventArgs</param>
|
|
|
- protected virtual void OnPropertyChanged(PropertyChangedEventArgs args)
|
|
|
- {
|
|
|
- PropertyChanged?.Invoke(this, args);
|
|
|
- }
|
|
|
- #endregion
|
|
|
- }
|
|
|
-}
|
|
|
+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;
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 正在采集
|
|
|
+ /// </summary>
|
|
|
+ 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; }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 采集用时
|
|
|
+ /// </summary>
|
|
|
+ public TimeSpan TotalTime { get; private set; }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 错误信息
|
|
|
+ /// </summary>
|
|
|
+ public string ErrorMessage { get; private set; }
|
|
|
+
|
|
|
+ private bool IsHaveCamera = false;
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region 事件
|
|
|
+ public event Action<ICogImage, TimeSpan, string> ImageCallbackEvent;
|
|
|
+ public event Action<Guid, bool> 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 方法
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 获取设备
|
|
|
+ /// </summary>
|
|
|
+ /// <returns></returns>
|
|
|
+ public static CameraInfo[] GetDevices()
|
|
|
+ {
|
|
|
+ List<CameraInfo> cameras = new List<CameraInfo>();
|
|
|
+ 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();
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 检查相机软件是否安装
|
|
|
+ /// </summary>
|
|
|
+ /// <returns></returns>
|
|
|
+ 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, "");
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 打开相机
|
|
|
+ /// </summary>
|
|
|
+ /// <returns></returns>
|
|
|
+ /// <exception cref="Exception"></exception>
|
|
|
+ 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();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 打开相机异步
|
|
|
+ /// </summary>
|
|
|
+ /// <returns></returns>
|
|
|
+ public Task<bool> OpenDeviceAsync()
|
|
|
+ {
|
|
|
+ return Task.Run(() =>
|
|
|
+ {
|
|
|
+ return OpenDevice();
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 关闭相机
|
|
|
+ /// </summary>
|
|
|
+ public void CloseDevice()
|
|
|
+ {
|
|
|
+ EnterOperation();
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if (CameraAcq!=null)
|
|
|
+ {
|
|
|
+ CameraAcq = null;
|
|
|
+
|
|
|
+ }
|
|
|
+ IsConnected = false;
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ ExitOperation();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 采集图像
|
|
|
+ /// </summary>
|
|
|
+ /// <returns></returns>
|
|
|
+ public ICogImage Grab()
|
|
|
+ {
|
|
|
+ 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();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 开始采集图像
|
|
|
+ /// </summary>
|
|
|
+ public void StartGrabbing()
|
|
|
+ {
|
|
|
+ lock (_stateLock)
|
|
|
+ {
|
|
|
+ if (IsGrabbing)
|
|
|
+ return;
|
|
|
+ IsGrabbing = true;
|
|
|
+ }
|
|
|
+ m_hReceiveThread = new Thread(GetStreamThreadProc) { IsBackground = true };
|
|
|
+ m_hReceiveThread.Start();
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 停止采集图像
|
|
|
+ /// </summary>
|
|
|
+ public void StopGrabbing()
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ lock (_stateLock)
|
|
|
+ {
|
|
|
+ IsGrabbing = false;
|
|
|
+ }
|
|
|
+ Thread.Sleep(1000);
|
|
|
+ if (m_hReceiveThread != null)
|
|
|
+ {
|
|
|
+ m_hReceiveThread.Abort();
|
|
|
+ m_hReceiveThread = null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (Exception)
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 设置曝光时间
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="ExposureTime"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public bool SetExposureTime(float ExposureTime)
|
|
|
+ {
|
|
|
+ EnterOperation();
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if (CameraAcq==null)
|
|
|
+ return false;
|
|
|
+ CameraAcq.OwnedExposureParams.Exposure = (double)ExposureTime;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ ExitOperation();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 获取曝光时间
|
|
|
+ /// </summary>
|
|
|
+ /// <returns></returns>
|
|
|
+ public float GetExposureTime()
|
|
|
+ {
|
|
|
+ EnterOperation();
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if (CameraAcq == null)
|
|
|
+ return 0;
|
|
|
+ return (float)CameraAcq.OwnedExposureParams.Exposure;
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ ExitOperation();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 设置增益
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="Gain"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public bool SetGain(float Gain)
|
|
|
+ {
|
|
|
+ EnterOperation();
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if (CameraAcq==null)
|
|
|
+ return false;
|
|
|
+ // 设置增益
|
|
|
+ CameraAcq.OwnedBrightnessParams.Brightness = (double)Gain;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ ExitOperation();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 获取增益
|
|
|
+ /// </summary>
|
|
|
+ /// <returns></returns>
|
|
|
+ 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 属性通知
|
|
|
+ /// <summary>
|
|
|
+ /// Occurs when a property value changes.
|
|
|
+ /// </summary>
|
|
|
+ public event PropertyChangedEventHandler PropertyChanged;
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Checks if a property already matches a desired value. Sets the property and
|
|
|
+ /// notifies listeners only when necessary.
|
|
|
+ protected virtual bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
|
|
|
+ {
|
|
|
+ if (EqualityComparer<T>.Default.Equals(storage, value)) return false;
|
|
|
+
|
|
|
+ storage = value;
|
|
|
+ RaisePropertyChanged(propertyName);
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Checks if a property already matches a desired value. Sets the property and
|
|
|
+ /// notifies listeners only when necessary.
|
|
|
+ /// </summary>
|
|
|
+ /// <typeparam name="T">Type of the property.</typeparam>
|
|
|
+ /// <param name="storage">Reference to a property with both getter and setter.</param>
|
|
|
+ /// <param name="value">Desired value for the property.</param>
|
|
|
+ /// <param name="propertyName">Name of the property used to notify listeners. This
|
|
|
+ /// value is optional and can be provided automatically when invoked from compilers that
|
|
|
+ /// support CallerMemberName.</param>
|
|
|
+ /// <param name="onChanged">Action that is called after the property value has been changed.</param>
|
|
|
+ /// <returns>True if the value was changed, false if the existing value matched the
|
|
|
+ /// desired value.</returns>
|
|
|
+ protected virtual bool SetProperty<T>(ref T storage, T value, Action onChanged, [CallerMemberName] string propertyName = null)
|
|
|
+ {
|
|
|
+ if (EqualityComparer<T>.Default.Equals(storage, value)) return false;
|
|
|
+
|
|
|
+ storage = value;
|
|
|
+ onChanged?.Invoke();
|
|
|
+ RaisePropertyChanged(propertyName);
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Raises this object's PropertyChanged event.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="propertyName">Name of the property used to notify listeners. This
|
|
|
+ /// value is optional and can be provided automatically when invoked from compilers
|
|
|
+ /// that support <see cref="CallerMemberNameAttribute"/>.</param>
|
|
|
+ protected void RaisePropertyChanged([CallerMemberName] string propertyName = null)
|
|
|
+ {
|
|
|
+ OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Raises this object's PropertyChanged event.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="args">The PropertyChangedEventArgs</param>
|
|
|
+ protected virtual void OnPropertyChanged(PropertyChangedEventArgs args)
|
|
|
+ {
|
|
|
+ PropertyChanged?.Invoke(this, args);
|
|
|
+ }
|
|
|
+ #endregion
|
|
|
+ }
|
|
|
+}
|