You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

412 lines
13 KiB
C#

using GxIAPINET;
using HalconDotNet;
using Rs.Framework;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace Rs.Cameras
{
public class DaHengCameras
{
private static DaHengCameras instance;
public static DaHengCameras Instance
{
get
{
if (instance == null)
instance = new DaHengCameras();
return instance;
}
}
private DaHengCameras()
{
}
List<DaHengCameraInfo> cameraInfos = new List<DaHengCameraInfo>();
public List<DaHengCameraInfo> Init()
{
IGXFactory.GetInstance().Init();
List<IGXDeviceInfo> infos = new List<IGXDeviceInfo>();
IGXFactory.GetInstance().UpdateAllDeviceList(1000, infos);
if(infos!=null && infos.Count>0)
{
foreach (IGXDeviceInfo devInfo in infos)
{
try
{
string userID = string.Empty;
userID = devInfo.GetUserID();
if(!string.IsNullOrEmpty(userID))
{
IGXDevice dev = IGXFactory.GetInstance().OpenDeviceByUserID(userID, GX_ACCESS_MODE.GX_ACCESS_EXCLUSIVE);
IGXFeatureControl featureControl = dev.GetRemoteFeatureControl();
IGXStream stream = dev.OpenStream(0);
IGXFeatureControl streamFeatureControl = stream.GetFeatureControl();
GX_DEVICE_CLASS_LIST objDeviceClass = dev.GetDeviceInfo().GetDeviceClass();
if (GX_DEVICE_CLASS_LIST.GX_DEVICE_CLASS_GEV == objDeviceClass)
{
// 判断设备是否支持流通道数据包功能
if (true == featureControl.IsImplemented("GevSCPSPacketSize"))
{
// 获取当前网络环境的最优包长值
uint nPacketSize = stream.GetOptimalPacketSize();
// 将最优包长值设置为当前设备的流通道包长值
featureControl.GetIntFeature("GevSCPSPacketSize").SetValue(nPacketSize);
}
}
featureControl.GetEnumFeature("AcquisitionMode").SetValue("Continuous");
//m_objIGXStreamFeatureControl = stream.GetFeatureControl();
DaHengCameraInfo camInfo = new DaHengCameraInfo(userID, dev, featureControl, stream, streamFeatureControl);
cameraInfos.Add(camInfo);
camInfo.SetTrigger(ETriggerSource.Line0);
camInfo.SetExposure(50);
camInfo.SetGain(10);
camInfo.StartGrabbing();
MessageQueue.Instance.Insert($"Camera {userID} opened success");
}
}
catch (Exception ex)
{
MessageQueue.Instance.Warn(ex.Message);
}
}
}
else
{
LogHelper.Debug($"cann't find camera");
}
return cameraInfos;
}
/// <summary>
/// 根据相机名称获取相机
/// </summary>
/// <param name="cameraName"></param>
/// <returns></returns>
public DaHengCameraInfo GetCameraInfo(string cameraName)
{
return cameraInfos.Where(c => c.CameraName == cameraName).FirstOrDefault();
}
/// <summary>
/// 获取所有的相机
/// </summary>
/// <returns></returns>
public List<DaHengCameraInfo> GetAllCameras()
{
return cameraInfos;
}
public void Deinit()
{
foreach (DaHengCameraInfo ci in cameraInfos)
{
ci.Deinit();
}
}
}
/// <summary>
/// 相机信息
/// </summary>
public class DaHengCameraInfo
{
public IGXDevice Camera { get; set; }
/// <summary>
/// 属性控制
/// </summary>
IGXFeatureControl featureControl;
IGXStream stream;
IGXFeatureControl streamFeatureControl;
public string CameraName { get; set; }
public int Index { get; set; }
private List<TakePicResult> Images;
public event Action<TakePicResult> OnImageLoaded;
public DaHengCameraInfo(string userID,IGXDevice _dev, IGXFeatureControl _featureControl, IGXStream _stream, IGXFeatureControl _streamFeatureControl)
{
CameraName = userID;
this.Camera = _dev;
this.featureControl = _featureControl;
this.stream = _stream;
streamFeatureControl = _streamFeatureControl;
Images = new List<TakePicResult>();
}
public void Deinit()
{
if (Camera != null)
{
featureControl.GetCommandFeature("AcquisitionStop").Execute();
stream.StopGrab();
//注销采集回调函数
// m_objIGXStream.UnregisterCaptureCallback();
stream.Close();
stream = null;
featureControl = null;
Camera.Close();
}
}
/// <summary>
/// 清除内存中的图片
/// </summary>
public void ClearImage()
{
lock (this)
{
if (Images != null)
{
Images.Clear();
}
}
}
/// <summary>
/// 取图
/// </summary>
/// <returns></returns>
public void Grab()
{
if (Camera != null)
{
featureControl.GetCommandFeature("TriggerSoftware").Execute();
}
}
public void StartGrabbing()
{
if (Camera != null && streamFeatureControl!=null && stream!=null)
{
streamFeatureControl.GetEnumFeature("StreamBufferHandlingMode").SetValue("OldestFirst");
stream.RegisterCaptureCallback(this, CaptureCallbackPro);
stream.StartGrab();
featureControl.GetCommandFeature("AcquisitionStart").Execute();
}
}
/// <summary>
/// 回调函数,用于获取图像信息和显示图像
/// </summary>
/// <param name="obj">用户自定义传入参数</param>
/// <param name="objIFrameData">图像信息对象</param>
private void CaptureCallbackPro(object objUserParam, IFrameData objIFrameData)
{
try
{
TakePicResult result = new TakePicResult();
LogHelper.Debug($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}-> 收到相机数据");
result.TakeTime = DateTime.Now;
//string msg = $"{trayNum},{rowNum},{slotNum},{dt.ToString("yyyy-MM-dd HH:mm:ss fff")},{GetTimeStamp(dt,true)}\r\n";
//File.AppendAllText("d://temp/test.csv", msg);
HObject image;
HOperatorSet.GenEmptyObj(out image);
image.Dispose();
HOperatorSet.GenImage1(out image, "byte", objIFrameData.GetWidth(), objIFrameData.GetHeight(), objIFrameData.GetBuffer());
result.SourceImage = image;
//HOperatorSet.WriteImage(image, "bmp", 0, $"d://temp//{trayNum}_{rowNum}_{slotNum}");
//HOperatorSet.WriteImage(image, "tiff",0, "d://d");
AddImage(result);
//GxSingleCam objGxSingleCam = objUserParam as GxSingleCam;
//objGxSingleCam.ImageShowAndSave(objIFrameData);
}
catch (Exception)
{
}
}
public void AddImage(TakePicResult result)
{
lock (this)
{
Images.Add(result);
OnImageLoaded?.Invoke(result);
}
}
/// <summary>
/// 设置曝光时间
/// </summary>
/// <param name="timer"></param>
/// <returns></returns>
public void SetExposure(double timer)
{
if (Camera != null && featureControl != null)
{
featureControl.GetFloatFeature("ExposureTime").SetValue(timer);
}
}
/// <summary>
/// 设置相机增益
/// </summary>
/// <param name="camName"></param>
/// <param name="gain"></param>
/// <returns></returns>
public void SetGain(double gain)
{
if (Camera != null && featureControl != null)
{
featureControl.GetFloatFeature("Gain").SetValue(gain);
}
}
/// <summary>
/// 设置相机的触发模式
/// </summary>
/// <param name="camName"></param>
/// <param name="triggerSource"></param>
/// <returns></returns>
public void SetTrigger(ETriggerSource triggerSource = ETriggerSource.Line0)
{
if (Camera != null)
{
if (triggerSource == ETriggerSource.Line0)
{
featureControl.GetEnumFeature("TriggerMode").SetValue("On");
featureControl.GetEnumFeature("TriggerSource").SetValue(ETriggerSource.Line0.ToString());
featureControl.GetEnumFeature("TriggerActivation").SetValue("RisingEdge");
}
else
{
featureControl.GetEnumFeature("TriggerMode").SetValue("On");
featureControl.GetEnumFeature("TriggerSource").SetValue(ETriggerSource.Software.ToString());
}
}
}
/// <summary>
/// 设置相机XY方向是否反转
/// </summary>
/// <param name="camName"></param>
/// <param name="dir"></param>
/// <param name="reverse"></param>
/// <returns></returns>
public int SetReverse(EDir dir = EDir.X, bool reverse = false)
{
if (Camera != null)
{
if (dir == EDir.X)
{
featureControl.GetBoolFeature("ReverseX").SetValue(reverse);
}
else
{
featureControl.GetBoolFeature("ReverseY").SetValue(reverse);
}
}
else
{
return -1;
}
return 0;
}
/// <summary>
/// 获取最后一张图片
/// </summary>
/// <returns></returns>
public TakePicResult GetLastImage()
{
lock (this)
{
if (Images != null && Images.Count > 0)
{
return Images[Images.Count - 1];
}
return null;
}
}
/// <summary>
/// 获取所有的图片
/// </summary>
/// <returns></returns>
public List<TakePicResult> GetAllImages()
{
lock (this)
{
return Images;
}
}
/// <summary>
/// 获取图片数量
/// </summary>
/// <returns></returns>
public int GetImageCount()
{
lock (this)
{
if (Images != null && Images.Count > 0)
{
return Images.Count;
}
return 0;
}
}
public static long GetTimeStamp(DateTime dt,bool ismilliseconds = false)
{
//时间戳 毫秒值
//var time = new DateTimeOffset(DateTime.UtcNow);
var time = new DateTimeOffset(dt);
var timestamp = 0L;
if (ismilliseconds)
{
timestamp = time.ToUnixTimeMilliseconds();
}
else
timestamp = time.ToUnixTimeSeconds();
return timestamp;
}
}
/// <summary>
/// 取图结果类
/// </summary>
public class TakePicResult
{
/// <summary>
/// 原图
/// </summary>
public HObject SourceImage { get; set; }
/// <summary>
/// 相机返回图片时间
/// </summary>
public DateTime TakeTime { get; set; }
/// <summary>
/// 二维码
/// </summary>
public string SN { get; set; }
public TakePicResult()
{
}
public TakePicResult(HObject sourceImage, DateTime takeTime)
{
SourceImage = sourceImage;
TakeTime = takeTime;
}
}
}