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.
450 lines
14 KiB
C#
450 lines
14 KiB
C#
using HalconDotNet;
|
|
using MvCamCtrl.NET;
|
|
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 HikCameras
|
|
{
|
|
private static HikCameras instance;
|
|
public static HikCameras Instance
|
|
{
|
|
get
|
|
{
|
|
if (instance == null)
|
|
instance = new HikCameras();
|
|
return instance;
|
|
}
|
|
}
|
|
|
|
|
|
private HikCameras()
|
|
{
|
|
cbImage = new MyCamera.cbOutputExdelegate(ImageCallBack);
|
|
}
|
|
|
|
MyCamera.MV_CC_DEVICE_INFO_LIST m_pDeviceList;
|
|
int apiResult = 0;
|
|
MyCamera.cbOutputExdelegate cbImage;
|
|
IntPtr m_BufForDriver = IntPtr.Zero;
|
|
List<CameraInfo> cameraInfos = new List<CameraInfo>();
|
|
|
|
private void ImageCallBack(IntPtr pData, ref MyCamera.MV_FRAME_OUT_INFO_EX pFrameInfo, IntPtr pUser)
|
|
{
|
|
LogHelper.Debug("收到相机数据");
|
|
HObject image;
|
|
HOperatorSet.GenEmptyObj(out image);
|
|
image.Dispose();
|
|
int nIndex = (int)pUser;
|
|
HOperatorSet.GenImage1(out image, "byte", pFrameInfo.nWidth, pFrameInfo.nHeight, pData);
|
|
CameraInfo ci = GetCameraInfo(nIndex);
|
|
if (ci != null)
|
|
{
|
|
ci.AddImage(image);
|
|
}
|
|
}
|
|
|
|
public List<CameraInfo> Init()
|
|
{
|
|
int nRet = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref m_pDeviceList);
|
|
if (nRet != 0)
|
|
{
|
|
LogHelper.Debug($"MV_CC_EnumDevices_NET ret = {nRet}");
|
|
//未找到任何相机
|
|
return null;
|
|
}
|
|
else if (m_pDeviceList.nDeviceNum>0)
|
|
{
|
|
for (int i = 0; i < m_pDeviceList.nDeviceNum; i++)
|
|
{
|
|
string cameraInfo = string.Empty;
|
|
///获取相机信息
|
|
MyCamera.MV_CC_DEVICE_INFO device = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(m_pDeviceList.pDeviceInfo[i], typeof(MyCamera.MV_CC_DEVICE_INFO));
|
|
if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE)
|
|
{
|
|
MyCamera.MV_GIGE_DEVICE_INFO gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO)MyCamera.ByteToStruct(device.SpecialInfo.stGigEInfo, typeof(MyCamera.MV_GIGE_DEVICE_INFO));
|
|
if(!string.IsNullOrEmpty(gigeInfo.chUserDefinedName))
|
|
{
|
|
cameraInfo = gigeInfo.chUserDefinedName;
|
|
}// gigeInfo.chModelName + " (" + gigeInfo.chSerialNumber + ")";
|
|
else
|
|
{
|
|
cameraInfo = gigeInfo.chSerialNumber;
|
|
}
|
|
}
|
|
else if (device.nTLayerType == MyCamera.MV_USB_DEVICE)
|
|
{
|
|
MyCamera.MV_USB3_DEVICE_INFO usbInfo = (MyCamera.MV_USB3_DEVICE_INFO)MyCamera.ByteToStruct(device.SpecialInfo.stGigEInfo, typeof(MyCamera.MV_USB3_DEVICE_INFO));
|
|
if (!string.IsNullOrEmpty(usbInfo.chUserDefinedName))
|
|
{
|
|
cameraInfo = usbInfo.chUserDefinedName;
|
|
}
|
|
else
|
|
{
|
|
cameraInfo = usbInfo.chSerialNumber;
|
|
}
|
|
}
|
|
|
|
MyCamera camera = new MyCamera();
|
|
apiResult = camera.MV_CC_CreateDevice_NET(ref device);
|
|
if (apiResult != 0)
|
|
{
|
|
LogHelper.Debug($"MV_CC_CreateDevice_NET ret = {apiResult}");
|
|
//MV_CC_CreateDevice_NET fail;
|
|
//return ECameraErrorCode.CreateDeviceFail;
|
|
continue;
|
|
}
|
|
apiResult = camera.MV_CC_OpenDevice_NET();
|
|
if (apiResult != 0)
|
|
{
|
|
LogHelper.Debug($"MV_CC_OpenDevice_NET ret = {apiResult}");
|
|
//return ECameraErrorCode.OpenDeviceFail;
|
|
continue;
|
|
}
|
|
if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE)
|
|
{
|
|
int nPacketSize = camera.MV_CC_GetOptimalPacketSize_NET();
|
|
if (nPacketSize > 0)
|
|
{
|
|
nRet = camera.MV_CC_SetIntValue_NET("GevSCPSPacketSize", (uint)nPacketSize);
|
|
if (nRet != MyCamera.MV_OK)
|
|
{
|
|
LogHelper.Debug($"MV_CC_SetIntValue_NET GevSCPSPacketSize ret = {apiResult}");
|
|
//return ECameraErrorCode.GevSCPSPacketSizeFail;
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//return ECameraErrorCode.GevSCPSPacketSizeFail;
|
|
continue;
|
|
}
|
|
}
|
|
apiResult = camera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON);
|
|
if (nRet != MyCamera.MV_OK)
|
|
{
|
|
LogHelper.Debug($"MV_CC_SetIntValue_NET TriggerMode ret = {apiResult}");
|
|
//return ECameraErrorCode.SetTriggerModeFail;
|
|
continue;
|
|
}
|
|
apiResult = camera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE);
|
|
if (nRet != MyCamera.MV_OK)
|
|
{
|
|
LogHelper.Debug($"MV_CC_SetIntValue_NET TriggerSource ret = {apiResult}");
|
|
//return ECameraErrorCode.SetTriggerSourceFail;
|
|
continue;
|
|
}
|
|
apiResult = camera.MV_CC_RegisterImageCallBackEx_NET(cbImage, (IntPtr)i);
|
|
if (apiResult != 0)
|
|
{
|
|
LogHelper.Debug($"MV_CC_RegisterImageCallBackEx_NET ret = {apiResult}");
|
|
continue;
|
|
//return ECameraErrorCode.RegisterImageCallBackExFail;
|
|
}
|
|
CameraInfo ci = new CameraInfo();
|
|
ci.Camera = camera;
|
|
ci.CameraName = cameraInfo;
|
|
ci.Index = i;
|
|
cameraInfos.Add(ci);
|
|
LogHelper.Debug($"Find camera {cameraInfo}");
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
//未找到任何相机
|
|
return null;
|
|
}
|
|
return cameraInfos;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 根据相机名称获取相机
|
|
/// </summary>
|
|
/// <param name="cameraName"></param>
|
|
/// <returns></returns>
|
|
public CameraInfo GetCameraInfo(string cameraName)
|
|
{
|
|
return cameraInfos.Where(c=>c.CameraName==cameraName).FirstOrDefault();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 根据索引获取相机
|
|
/// </summary>
|
|
/// <param name="index"></param>
|
|
/// <returns></returns>
|
|
private CameraInfo GetCameraInfo(int index)
|
|
{
|
|
return cameraInfos.Where(c => c.Index == index).FirstOrDefault();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取所有的相机
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public List<CameraInfo> GetAllCameras()
|
|
{
|
|
return cameraInfos;
|
|
}
|
|
|
|
public void Deinit()
|
|
{
|
|
foreach (CameraInfo ci in cameraInfos)
|
|
{
|
|
ci.Deinit();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 相机信息
|
|
/// </summary>
|
|
public class CameraInfo
|
|
{
|
|
public MyCamera Camera { get; set; }
|
|
public string CameraName { get; set; }
|
|
|
|
public int Index { get; set; }
|
|
|
|
private List<HObject> Images;
|
|
|
|
int apiResult = -1;
|
|
|
|
public CameraInfo()
|
|
{
|
|
Images = new List<HObject>();
|
|
}
|
|
|
|
public void Deinit()
|
|
{
|
|
if(Camera != null)
|
|
{
|
|
Camera.MV_CC_CloseDevice_NET();
|
|
Camera.MV_CC_DestroyDevice_NET();
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 清除内存中的图片
|
|
/// </summary>
|
|
public void ClearImage()
|
|
{
|
|
lock(this)
|
|
{
|
|
if (Images != null)
|
|
{
|
|
Images.Clear();
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 取图
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public int Grab()
|
|
{
|
|
if (Camera != null)
|
|
return Camera.MV_CC_SetCommandValue_NET("TriggerSoftware");
|
|
return -1;
|
|
}
|
|
|
|
public int StartGrabbing()
|
|
{
|
|
if (Camera != null)
|
|
return Camera.MV_CC_StartGrabbing_NET();
|
|
return -1;
|
|
}
|
|
|
|
public void AddImage(HObject image)
|
|
{
|
|
lock (this)
|
|
{
|
|
Images.Add(image);
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置曝光时间
|
|
/// </summary>
|
|
/// <param name="timer"></param>
|
|
/// <returns></returns>
|
|
public int SetExposure(float timer)
|
|
{
|
|
if (Camera != null)
|
|
{
|
|
apiResult = Camera.MV_CC_SetEnumValue_NET("ExposureAuto", 0);
|
|
if (apiResult != 0)
|
|
{
|
|
|
|
return apiResult;
|
|
}
|
|
apiResult = Camera.MV_CC_SetFloatValue_NET("ExposureTime", timer);
|
|
if (apiResult != 0)
|
|
{
|
|
return apiResult;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置相机增益
|
|
/// </summary>
|
|
/// <param name="camName"></param>
|
|
/// <param name="gain"></param>
|
|
/// <returns></returns>
|
|
public int SetGain(float gain)
|
|
{
|
|
if (Camera != null)
|
|
{
|
|
apiResult = Camera.MV_CC_SetEnumValue_NET("GainAuto", 0);
|
|
if (apiResult != 0)
|
|
{
|
|
return apiResult;
|
|
}
|
|
apiResult = Camera.MV_CC_SetFloatValue_NET("Gain", gain);
|
|
if (apiResult != 0)
|
|
{
|
|
return apiResult;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置相机的触发模式
|
|
/// </summary>
|
|
/// <param name="camName"></param>
|
|
/// <param name="triggerSource"></param>
|
|
/// <returns></returns>
|
|
public int SetTrigger(ETriggerSource triggerSource = ETriggerSource.Line0)
|
|
{
|
|
if(Camera!=null)
|
|
{
|
|
if (triggerSource == ETriggerSource.Line0)
|
|
{
|
|
apiResult = Camera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_LINE0);
|
|
if (apiResult != 0)
|
|
{
|
|
apiResult = Camera.MV_CC_SetEnumValue_NET("TriggerActivation", 0);//设置上升沿触发
|
|
if (apiResult != 0)
|
|
{
|
|
return apiResult;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return apiResult;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
apiResult = Camera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE);
|
|
if (apiResult != 0)
|
|
{
|
|
return apiResult;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/// <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)
|
|
{
|
|
apiResult = Camera.MV_CC_SetBoolValue_NET("ReverseX", reverse);
|
|
if (apiResult != 0)
|
|
return apiResult;
|
|
}
|
|
else
|
|
{
|
|
apiResult = Camera.MV_CC_SetBoolValue_NET("ReverseY", reverse);
|
|
if (apiResult != 0)
|
|
return apiResult;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取最后一张图片
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public HObject GetLastImage()
|
|
{
|
|
lock (this)
|
|
{
|
|
if (Images != null && Images.Count > 0)
|
|
{
|
|
return Images[Images.Count - 1];
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取所有的图片
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public List<HObject> 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;
|
|
}
|
|
}
|
|
}
|
|
}
|