geboshi_V1/LeatherProject/LeatherApp/Device/CamerCardDevIK.cs

876 lines
37 KiB
C#
Raw Normal View History

2024-03-07 14:03:22 +08:00
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;
using IKapBoardClassLibrary;
using IKapC.NET;
using LeatherApp.Device.CamerUtil;
using LeatherApp.Interface;
using Newtonsoft.Json.Linq;
using OpenCvSharp;
using OpenCvSharp.Dnn;
using ErrorCode = IKapBoardClassLibrary.ErrorCode;
namespace LeatherApp.Device
{
public class CamerCardDevIK : ABSCamerCardDev,IDisposable
{
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool IsWindow(IntPtr hWnd);
[DllImport("kernel32.dll")]
public static extern void CopyMemory(IntPtr Destination, IntPtr Source, int Length);
// 相机句柄
//private IKDeviceCL m_pDev = new IKDeviceCL();
public IntPtr m_pDev = new IntPtr(-1);
// 采集卡句柄
public IntPtr m_pBoard = new IntPtr(-1);
// 用户缓冲区,用于图像数据转换
public IntPtr m_pUserBuffer = new IntPtr(-1);
// 是否正在采集
public volatile bool m_bGrabingImage = false;
// 是否已更新用户缓冲区
public volatile bool m_bUpdateImage = false;
// 相机类型0为GV相机1为CL相机2为CXP相机
public int m_nType = -1;
// 图像宽度
public int m_nWidth = -1;
// 图像高度
public int m_nHeight = -1;
// 像素位数
public int m_nDepth = 8;
// 图像通道数
public int m_nChannels = 1;
// 相机索引
public int m_nDevIndex = -1;
// 采集卡索引
public int m_nBoardIndex = -1;
// 相机缓冲区个数
public int m_nFrameCount = 2;//只能1
// 当前帧索引
public int m_nCurFrameIndex = 0;
// 相机缓冲区大小
public int m_nBufferSize = 0;
// 用户缓冲区锁
public object m_mutexImage = new object();
//显示图像控件句柄
private PictureBox previewHwnd = null;
//
// 保存图像的文件名。
public string m_strFileName = "C:\\CSharpImage.bmp";
//
private int scanIndex = 0; //实际拍照从1开始命名因先加的1
private string bmpSavePath;
private Thread readerThread;
private Queue<MyData> frameQueue =new Queue<MyData>();
/// <summary>
/// 曝光 3.00-10000.00
/// </summary>
public float ExposureTime { get; private set; }
/// <summary>
/// 增益 0-23.981199
/// </summary>
public float Gain { get; private set; }
/// <summary>
/// 帧率 0-429496.718750
/// </summary>
public float ResultingFrameRate { get; private set; }
/// <summary>
/// 图片大小
/// </summary>
public System.Drawing.Size size { get; private set; }
/// <summary>
/// 是否打开设备成功
/// </summary>
public bool IsInit { get; private set; } = false;
//public string ErrInfo { get; private set; }
//private System.Timers.Timer timer = new System.Timers.Timer();
private int _scannerCardIndex = 0;//采集卡索引
private int _scannerIndex=0;//相机索引(一个采集卡上可插多个相机)
private IKDeviceInfo devInfo;
BufferToImage hBuffer;
private class MyData
{
public MyData(int _index,Mat _mat)
{
index= _index;
mat = _mat;
}
public int index;
public Mat mat;
}
// 设备类型枚举
enum IKDeviceType
{
DEVICE_NIL = 0,
DEVICE_CML,
DEVICE_CXP,
DEVICE_USB,
DEVICE_GIGEVISION
}
// 设备信息结构体
struct IKDeviceInfo
{
public IKDeviceType nType;
public int nDevIndex;
public int nBoardIndex;
public string sDevName;
}
/// <summary>
/// 读取缓存队列线程
/// </summary>
private void readDataThread()
{
MyData mydate;
while (IsInit)
{
if (frameQueue.Count > 0) // 如果队列不为空则从队列中获取元素
{
lock (frameQueue)
{
mydate = frameQueue.Dequeue();
}
PhotoNumCacheEvent?.Invoke(frameQueue.Count);
WarningEvent?.BeginInvoke(DateTime.Now,WarningEnum.Normal, $"相机({_scannerCardIndex})从缓存队列提取一帧图像({mydate.index}),开始回调(队列剩余帧数:{frameQueue.Count})...", null, null);
ScanEvent?.Invoke(mydate.index, mydate.mat, _scannerCardIndex);
WarningEvent?.BeginInvoke(DateTime.Now,WarningEnum.Normal, $"相机({_scannerCardIndex})图像({mydate.index})回调完成.", null, null);
}
else
{
Thread.Sleep(10);
}
}
}
public CamerCardDevIK( )
{
m_nType = 1;
}
public override bool open(int nBoardIndex,int nDevIndex)
{
if (IsInit) return true;
_scannerCardIndex = nBoardIndex;
WarningEvent?.BeginInvoke(DateTime.Now,WarningEnum.Normal, "open ....",null,null);
try
{
closeDevice();
scanIndex = 0;
devInfo = new IKDeviceInfo();
readerThread = new Thread(readDataThread); // 创建读取线程
//
uint nDevCount = 2;
uint res = IKapCLib.ItkManGetDeviceCount(ref nDevCount);
if (res != (uint)ItkStatusErrorId.ITKSTATUS_OK)
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.High, "ItkManGetDeviceCount failed");
return false;
}
IKapCLib.ITKDEV_INFO pDevInfo = new IKapCLib.ITKDEV_INFO();
IKapCLib.ITK_CL_DEV_INFO pClDevInfo = new IKapCLib.ITK_CL_DEV_INFO();
for (uint i = 0; i < nDevCount; ++i)
{
IKapCLib.ItkManGetDeviceInfo(i, ref pDevInfo);
if (pDevInfo.DeviceClass.CompareTo("CameraLink") == 0)
{
res = IKapCLib.ItkManGetCLDeviceInfo(i, ref pClDevInfo);
//if (res != (uint)ItkStatusErrorId.ITKSTATUS_OK)
// return;
if ((int)pClDevInfo.BoardIndex == nBoardIndex)
{
devInfo.nType = IKDeviceType.DEVICE_CML;
devInfo.nDevIndex = (int)i;
devInfo.nBoardIndex = (int)pClDevInfo.BoardIndex;
devInfo.sDevName = pDevInfo.FullName;
}
}
}
if(devInfo.nType != IKDeviceType.DEVICE_CML)
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.High, "对应索引相机不存在 failed");
return false;
}
//
res = IKapCLib.ItkDevOpen((uint)devInfo.nDevIndex
, (int)(ItkDeviceAccessMode.ITKDEV_VAL_ACCESS_MODE_CONTROL)
, ref m_pDev);
if (!Check(res))
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.High, "Camera error:Open camera failed");
return false;
}
//打开采集卡
m_pBoard = IKapBoard.IKapOpen((uint)BoardType.IKBoardPCIE, (uint)devInfo.nBoardIndex);
if (m_pBoard == new IntPtr(-1))
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.High, "IKapOpen failed");
return false;
}
IsInit = true;
readerThread.Start();
return true;
}
catch (Exception ex)
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.High, ex.Message);
return false;
}
}
public override void close()
{
if (!IsInit) return;
try
{
IsInit = false;
// 清除回调函数。
UnRegisterCallback();
// 关闭设备。
CloseDevice();
}
catch { }
}
/// <summary>
///
/// </summary>
/// <param name="hwnd">显示图像控件句柄</param>
/// <returns></returns>
public override bool start(PictureBox preview_Hwnd,string bmp_save_path)
{
if (!IsInit) return false;
WarningEvent?.Invoke(DateTime.Now,WarningEnum.Normal, "start ....");
// 导入配置文件。
string configFileName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\DevCfg\\" + (_scannerCardIndex==0?Config.Carmer1ConfigFilePath: Config.Carmer2ConfigFilePath);
if (!File.Exists(configFileName))
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.High, "Fail to get configuration, using default setting!");
return false;
}
var b=loadConfiguration(configFileName);
WarningEvent?.Invoke(DateTime.Now,WarningEnum.Normal, "开始采集 ..."+b.ToString());
this.previewHwnd= preview_Hwnd;
this.bmpSavePath = bmp_save_path;
//开始采集
//第二个参数 nFrameCount 表示希望 IKapBoardClassLibrary 采集的帧数。
//如果 nFrameCount = 1IKapBoardClassLibrary 会从相机中采集一帧图像;
//如果 nFrameCount = N 且 N> 1则 IKapBoardClassLibrary 从相机中采集连续的 N 帧图 像;
//如果 nFrameCount = 0则 IKapBoardClassLibrary 开始连续采集图像。
int ret;
// 设置抓取模式IKP_GRAB_NON_BLOCK为非阻塞模式
//int grab_mode = (int)GrabMode.IKP_GRAB_NON_BLOCK;
//ret = IKapBoard.IKapSetInfo(m_pBoard, (uint)INFO_ID.IKP_GRAB_MODE, grab_mode);
//if (ret != (int)ErrorCode.IK_RTN_OK)
// return false;
//// 设置帧传输模式IKP_FRAME_TRANSFER_SYNCHRONOUS_NEXT_EMPTY_WITH_PROTECT为同步保存模式
//int transfer_mode = (int)FrameTransferMode.IKP_FRAME_TRANSFER_SYNCHRONOUS_NEXT_EMPTY_WITH_PROTECT;
//ret = IKapBoard.IKapSetInfo(m_pBoard, (uint)INFO_ID.IKP_FRAME_TRANSFER_MODE, transfer_mode);
//if (ret != (int)ErrorCode.IK_RTN_OK)
// return false;
//设置缓冲区格式
ret = IKapBoard.IKapSetInfo(m_pBoard, (uint)INFO_ID.IKP_FRAME_COUNT, 1);//
if (ret != (int)ErrorCode.IK_RTN_OK)
return false;
// 设置帧超时时间
int timeout = -1;
ret = IKapBoard.IKapSetInfo(m_pBoard, (uint)INFO_ID.IKP_TIME_OUT, timeout);
if (ret != (int)ErrorCode.IK_RTN_OK)
return false;
// 设置采集模式。
//
// Set grab mode.
int grab_mode = (int)GrabMode.IKP_GRAB_NON_BLOCK;
ret = IKapBoard.IKapSetInfo(m_pBoard, (uint)INFO_ID.IKP_GRAB_MODE, grab_mode);
if (ret != (int)ErrorCode.IK_RTN_OK)
return false;
// 设置传输模式。
int transfer_mode = (int)FrameTransferMode.IKP_FRAME_TRANSFER_SYNCHRONOUS_NEXT_EMPTY_WITH_PROTECT;
ret = IKapBoard.IKapSetInfo(m_pBoard, (uint)INFO_ID.IKP_FRAME_TRANSFER_MODE, transfer_mode);
if (ret != (int)ErrorCode.IK_RTN_OK)
return false;
// 注册回调函数
IntPtr hPtr = new IntPtr(-1);
OnGrabStartProc = new IKapCallBackProc(OnGrabStartFunc);
ret = IKapBoard.IKapRegisterCallback(m_pBoard, (uint)CallBackEvents.IKEvent_GrabStart, Marshal.GetFunctionPointerForDelegate(OnGrabStartProc), hPtr);
if (ret != (int)ErrorCode.IK_RTN_OK)
return false;
OnFrameReadyProc = new IKapCallBackProc(OnFrameReadyFunc);
ret = IKapBoard.IKapRegisterCallback(m_pBoard, (uint)CallBackEvents.IKEvent_FrameReady, Marshal.GetFunctionPointerForDelegate(OnFrameReadyProc), hPtr);
if (ret != (int)ErrorCode.IK_RTN_OK)
return false;
OnFrameLostProc = new IKapCallBackProc(OnFrameLostFunc);
ret = IKapBoard.IKapRegisterCallback(m_pBoard, (uint)CallBackEvents.IKEvent_FrameLost, Marshal.GetFunctionPointerForDelegate(OnFrameLostProc), hPtr);
if (ret != (int)ErrorCode.IK_RTN_OK)
return false;
OnTimeoutProc = new IKapCallBackProc(OnTimeoutFunc);
ret = IKapBoard.IKapRegisterCallback(m_pBoard, (uint)CallBackEvents.IKEvent_TimeOut, Marshal.GetFunctionPointerForDelegate(OnTimeoutProc), hPtr);
if (ret != (int)ErrorCode.IK_RTN_OK)
return false;
OnGrabStopProc = new IKapCallBackProc(OnGrabStopFunc);
ret = IKapBoard.IKapRegisterCallback(m_pBoard, (uint)CallBackEvents.IKEvent_GrabStop, Marshal.GetFunctionPointerForDelegate(OnGrabStopProc), hPtr);
if (ret != (int)ErrorCode.IK_RTN_OK)
return false;
m_bUpdateImage = false;
m_nCurFrameIndex = 0;
ret = IKapBoard.IKapStartGrab(m_pBoard, 0);
if (ret != (int)ErrorCode.IK_RTN_OK)
return false;
//createBuffer
b = createBuffer();
if (!b)
return false;
getParam();
//
m_bGrabingImage = true;
return true;
}
/// <summary>
/// 停止采集
/// </summary>
public override void stop()
{
if (!IsInit) return;
try
{
// 停止图像采集。
var ret = IKapBoard.IKapStopGrab(m_pBoard);
clearBuffer();
CheckIKapBoard(ret);
}
catch
{
return;
}
}
/// <summary>
/// num 因拍了一张后回传的当前已经是1了
/// </summary>
/// <param name="num"></param>
public override void resetScanIndex()
{
scanIndex = 0;//
}
public override void getParam()
{
if (!IsInit) return;
string result;
result = getFeatureValue("ExposureTime");
if (!string.IsNullOrEmpty(result))
ExposureTime = Convert.ToSingle(result);
result = getFeatureValue("Gain");
if (!string.IsNullOrEmpty(result))
Gain = Convert.ToSingle(result);
}
/// <summary>
///
/// </summary>
/// <param name="exposureTime">曝光</param>
/// <param name="gain">增益</param>
/// <param name="resultingFrameRate">帧率</param>
public override bool setParam(float exposureTime, float gain =-1, float resultingFrameRate =-1)
{
if (!IsInit) return false;
bool change = false;
//WarningEvent?.Invoke(DateTime.Now,WarningEnum.Normal, $"ExposureTime: {exposureTime},{ExposureTime}");
if (exposureTime != ExposureTime && exposureTime != -1)
{
if(setFeatureValue("ExposureTime", exposureTime.ToString()))
change = true;
}
//WarningEvent?.Invoke(DateTime.Now,WarningEnum.Normal, $"Gain: {gain},{Gain}");
if (gain != Gain && gain != -1)
{
if (setFeatureValue("Gain", gain.ToString()))
change = true;
}
//if (resultingFrameRate != ResultingFrameRate && resultingFrameRate != -1)
//{
// cDeviceParam.SetFloatValue("AcquisitionFrameRate", resultingFrameRate);
// change = true;
//}
//
if (change)
getParam();
return change;
}
public void Dispose()
{
stop();
close();
}
//---------------
/* @brief
*
* @briefSet line trigger parameters. */
void SetLineTrigger()
{
int ret = (int)ErrorCode.IK_RTN_OK;
// 设置CC1信号源。
//
// Set CC1 signal source.
ret = IKapBoard.IKapSetInfo(m_pBoard, (uint)INFO_ID.IKP_CC1_SOURCE, (int)CCSource.IKP_CC_SOURCE_VAL_INTEGRATION_SIGNAL1);
CheckIKapBoard(ret);
// 设置积分控制方法触发信号源。
//
// Set integration control method trigger source.
ret = IKapBoard.IKapSetInfo(m_pBoard, (uint)INFO_ID.IKP_INTEGRATION_TRIGGER_SOURCE, (int)IntegrationTriggerSource.IKP_INTEGRATION_TRIGGER_SOURCE_VAL_SHAFT_ENCODER1);
CheckIKapBoard(ret);
}
/* @brief
*
* @briefUnregister callback functions. */
private void UnRegisterCallback()
{
int ret = (int)ErrorCode.IK_RTN_OK;
ret = IKapBoard.IKapUnRegisterCallback(m_pBoard, (uint)CallBackEvents.IKEvent_GrabStart);
ret = IKapBoard.IKapUnRegisterCallback(m_pBoard, (uint)CallBackEvents.IKEvent_FrameReady);
ret = IKapBoard.IKapUnRegisterCallback(m_pBoard, (uint)CallBackEvents.IKEvent_FrameLost);
ret = IKapBoard.IKapUnRegisterCallback(m_pBoard, (uint)CallBackEvents.IKEvent_TimeOut);
ret = IKapBoard.IKapUnRegisterCallback(m_pBoard, (uint)CallBackEvents.IKEvent_GrabStop);
}
/* @brief
*
* @briefClose device. */
private void CloseDevice()
{
// 关闭采集卡设备。
//
// Close frame grabber device.
if (!m_pBoard.Equals(-1))
{
IKapBoard.IKapClose(m_pBoard);
m_pBoard = (IntPtr)(-1);
}
}
/* @brief IKapBoard
* @param[in] ret
*
* @briefDetermine whether the IKapBoard function is called successfully.
* @param[in] retFunction return value. */
static void CheckIKapBoard(int ret)
{
if (ret != (int)ErrorCode.IK_RTN_OK)
{
string sErrMsg = "";
IKapBoard.IKAPERRORINFO tIKei = new IKapBoardClassLibrary.IKapBoard.IKAPERRORINFO();
// 获取错误码信息。
IKapBoard.IKapGetLastError(ref tIKei, true);
// 打印错误信息。
sErrMsg = string.Concat("Error",
sErrMsg,
"Board Type\t = 0x", tIKei.uBoardType.ToString("X4"), "\n",
"Board Index\t = 0x", tIKei.uBoardIndex.ToString("X4"), "\n",
"Error Code\t = 0x", tIKei.uErrorCode.ToString("X4"), "\n"
);
throw new Exception(sErrMsg);
}
}
#region Callback
delegate void IKapCallBackProc(IntPtr pParam);
/* @brief
*
* @briefThis function is registered as a callback function. When starting grabbing images, the function will be called. */
private IKapCallBackProc OnGrabStartProc;
/* @brief
*
* @briefThis function is registered as a callback function. When grabbing frame lost, the function will be called. */
private IKapCallBackProc OnFrameLostProc;
/* @brief
*
* @briefThis function is registered as a callback function. When grabbing images time out, the function will be called. */
private IKapCallBackProc OnTimeoutProc;
/* @brief
*
* @briefThis function is registered as a callback function. When a frame of image grabbing ready, the function will be called. */
private IKapCallBackProc OnFrameReadyProc;
/* @brief
*
* @briefThis function is registered as a callback function. When stopping grabbing images, the function will be called. */
private IKapCallBackProc OnGrabStopProc;
#endregion
#region Callback
/* @brief
* @param[in] pParam
*
* @briefThis function is registered as a callback function. When starting grabbing images, the function will be called.
* @param[in] pParamInput parameter. */
public void OnGrabStartFunc(IntPtr pParam)
{
WarningEvent?.BeginInvoke(DateTime.Now,WarningEnum.Normal, "图像开始采集...", null, null);
}
/* @brief
* @param[in] pParam
*
* @briefThis function is registered as a callback function. When grabbing frame lost, the function will be called.
* @param[in] pParamInput parameter. */
public void OnFrameLostFunc(IntPtr pParam)
{
WarningEvent?.BeginInvoke(DateTime.Now,WarningEnum.High, $"相机({_scannerCardIndex})采集图像({scanIndex})丢帧(Image frame lost),急停告警,需结束重新开始!!!", null, null);
}
/* @brief
* @param[in] pParam
*
* @briefThis function is registered as a callback function. When grabbing images time out, the function will be called.
* @param[in] pParamInput parameter. */
public void OnTimeoutFunc(IntPtr pParam)
{
WarningEvent?.BeginInvoke(DateTime.Now,WarningEnum.High, $"相机({_scannerCardIndex})采集图像({scanIndex})超时(Grab image timeout),请检查采集卡!", null, null);
}
/* @brief
* @param[in] pParam
*
* @briefThis function is registered as a callback function. When a frame of image grabbing ready, the function will be called.
* @param[in] pParamInput parameter. */
public void OnFrameReadyFunc(IntPtr pParam)
{
try
{
Stopwatch stopwatch = Stopwatch.StartNew();
stopwatch.Start();
int index = ++scanIndex;
WarningEvent?.BeginInvoke(DateTime.Now, WarningEnum.Normal, $"OnFrameReadyFunc 相机({_scannerCardIndex})一帧图像({index})采集完成,正在加入队列({frameQueue.Count})...", null, null);
IntPtr hPtr = new IntPtr(-1);
// 获取当前帧状态
var ret = IKapBoard.IKapGetInfo(m_pBoard, (uint)INFO_ID.IKP_CURRENT_BUFFER_INDEX, ref m_nCurFrameIndex);
if (ret != (int)ErrorCode.IK_RTN_OK)
return;
//IKapBoard.IKAPBUFFERSTATUS status = new IKapBoard.IKAPBUFFERSTATUS();
//IKapBoard.IKapGetBufferStatus(m_pBoard, m_nCurFrameIndex, ref status);
//var uFull = status.uFull;
//if (uFull == 1)//指明缓冲区是否为满
{
IKapBoard.IKapGetBufferAddress(m_pBoard, m_nCurFrameIndex, ref hPtr);
//Monitor.Enter(m_mutexImage);
lock (m_mutexImage)
{
CopyMemory(m_pUserBuffer, hPtr, m_nBufferSize);
m_bUpdateImage = true;
2024-08-05 09:39:58 +08:00
Mat mat = new Mat(m_nHeight, m_nWidth, MatType.CV_8UC3, m_pUserBuffer);
//var bmp = hBuffer.toBmp(m_pUserBuffer);
//Mat mat = OpenCvSharp.Extensions.BitmapConverter.ToMat(bmp);
//bmp.Dispose();
//bmp = null;
2024-03-07 14:03:22 +08:00
//Monitor.Enter(frameQueue);
lock (frameQueue)
2024-08-05 09:39:58 +08:00
frameQueue.Enqueue(new MyData(index, mat.Clone()));
2024-03-07 14:03:22 +08:00
PhotoNumCacheEvent?.BeginInvoke(frameQueue.Count, null, null);
}
}
//m_nCurFrameIndex++;
//m_nCurFrameIndex = m_nCurFrameIndex % m_nFrameCount;
stopwatch.Stop();
WarningEvent?.BeginInvoke(DateTime.Now, WarningEnum.Normal, $"OnFrameReadyFunc 相机({_scannerCardIndex})一帧图像({index})已加入队列({frameQueue.Count}).缓冲区索引={m_nCurFrameIndex};用时:{stopwatch.ElapsedMilliseconds}ms", null, null);
}
catch (Exception ex)
{
WarningEvent?.BeginInvoke(DateTime.Now, WarningEnum.High, $"OnFrameReadyFunc 异常,急停告警,需结束重新开始!!!{ex.Message}\r\n{ex.StackTrace}", null, null);
}
}
/* @brief
* @param[in] pParam
*
* @briefThis function is registered as a callback function. When stopping grabbing images, the function will be called.
* @param[in] pParamInput parameter. */
public void OnGrabStopFunc(IntPtr pParam)
{
Console.WriteLine("Stop grabbing image");
}
#endregion
private byte[] bmp2bytes(Bitmap bmp)
{
MemoryStream ms = new MemoryStream();
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
byte[] bytes = ms.GetBuffer(); //byte[] bytes= ms.ToArray(); 这两句都可以,至于区别么,下面有解释
ms.Close();
bmp.Dispose();
return bytes;
}
private Bitmap bytes2bmp(byte[] bytes)
{
MemoryStream ms1 = new MemoryStream(bytes);
Bitmap bm = (Bitmap)Image.FromStream(ms1);
ms1.Close();
return bm;
}
/*
* @brief:
* @param [in] featureName:[ExposureTime,Gain]
* @param [in] featureValue:
* @return:
*/
private bool setFeatureValue(string featureName, string featureValue)
{
IntPtr itkFeature = new IntPtr(-1);
uint nType = 0;
uint res = IKapCLib.ItkDevAllocFeature(m_pDev, featureName, ref itkFeature);
if (!Check(res))
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.Low, $"setFeatureValue({featureName},{featureValue}) Camera error:Allocate feature failed");
return false;
}
res = IKapCLib.ItkFeatureGetType(itkFeature, ref nType);
if (!Check(res))
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.Low, $"setFeatureValue({featureName},{featureValue}) Camera error:Get feature type failed");
return false;
}
switch (nType)
{
case (uint)ItkFeatureType.ITKFEATURE_VAL_TYPE_INT32:
res = IKapCLib.ItkFeatureSetInt32(itkFeature, Convert.ToInt32(featureValue));
break;
case (uint)ItkFeatureType.ITKFEATURE_VAL_TYPE_INT64:
res = IKapCLib.ItkFeatureSetInt64(itkFeature, Convert.ToInt64(featureValue));
break;
case (uint)ItkFeatureType.ITKFEATURE_VAL_TYPE_FLOAT:
case (uint)ItkFeatureType.ITKFEATURE_VAL_TYPE_DOUBLE:
res = IKapCLib.ItkFeatureSetDouble(itkFeature, Convert.ToDouble(featureValue));
break;
case (uint)ItkFeatureType.ITKFEATURE_VAL_TYPE_ENUM:
case (uint)ItkFeatureType.ITKFEATURE_VAL_TYPE_STRING:
res = IKapCLib.ItkFeatureFromString(itkFeature, featureValue);
break;
case (uint)ItkFeatureType.ITKFEATURE_VAL_TYPE_COMMAND:
res = IKapCLib.ItkFeatureExecuteCommand(itkFeature);
break;
}
if (!Check(res))
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.Low, $"setFeatureValue({featureName},{featureValue}) Camera error:Set feature failed:" + res);
return false;
}
return true;
}
private string getFeatureValue(string featureName)
{
IntPtr itkFeature = new IntPtr(-1);
uint nType = 0;
uint res = IKapCLib.ItkDevAllocFeature(m_pDev, featureName, ref itkFeature);
if (!Check(res))
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.Low, $"getFeatureValue({featureName}) Camera error:Allocate feature failed");
return "";
}
res = IKapCLib.ItkFeatureGetType(itkFeature, ref nType);
if (!Check(res))
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.Low, $"getFeatureValue({featureName}) Camera error:Get feature type failed");
return "";
}
switch (nType)
{
case (uint)ItkFeatureType.ITKFEATURE_VAL_TYPE_INT32:
int result = 0;
res = IKapCLib.ItkFeatureGetInt32(itkFeature,ref result);
if (!Check(res))
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.Low, $"getFeatureValue({featureName}) Camera error:Get feature failed:" + res);
return "";
}
return result.ToString();
case (uint)ItkFeatureType.ITKFEATURE_VAL_TYPE_INT64:
long resultL = 0;
res = IKapCLib.ItkFeatureGetInt64(itkFeature, ref resultL);
if (!Check(res))
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.Low, $"getFeatureValue({featureName}) Camera error:Get feature failed:" + res);
return "";
}
return resultL.ToString();
case (uint)ItkFeatureType.ITKFEATURE_VAL_TYPE_FLOAT:
case (uint)ItkFeatureType.ITKFEATURE_VAL_TYPE_DOUBLE:
double resultD = 0;
res = IKapCLib.ItkFeatureGetDouble(itkFeature, ref resultD);
if (!Check(res))
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.Low, $"getFeatureValue({featureName}) Camera error:Get feature failed:" + res);
return "";
}
return resultD.ToString();
case (uint)ItkFeatureType.ITKFEATURE_VAL_TYPE_ENUM:
case (uint)ItkFeatureType.ITKFEATURE_VAL_TYPE_STRING:
string results = "";
res = IKapCLib.ItkFeatureFromString(itkFeature, results);
if (!Check(res))
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.Low, $"getFeatureValue({featureName}) Camera error:Get feature failed:" + res);
return "";
}
return results;
}
if (!Check(res))
{
WarningEvent?.Invoke(DateTime.Now,WarningEnum.Low, $"getFeatureValue({featureName}) Camera error:Get feature failed:" + res);
return "";
}
return "";
}
public override double[] getFeatureRangeValue(string featureName)
{
switch (featureName)
{
case "ExposureTime":
//return new double[2] {3.2,63997};
return new double[2] { 10, 200 };
case "Gain":
return new double[2] { 0.01, 8.00 };
default: return new double[0] { };
}
}
/*
*@brief:
*@param [in] err:
*@return:
*/
private static bool Check(uint err)
{
if (err != (uint)ItkStatusErrorId.ITKSTATUS_OK)
{
System.Diagnostics.Debug.WriteLine("Error code: {0}.\n", err.ToString("x8"));
return false;
}
return true;
}
//----
private bool isOpen()
{
return m_pDev != new IntPtr(-1) && m_pBoard != new IntPtr(-1);
}
private bool closeDevice()
{
frameQueue.Clear();
if (isOpen())
{
IKapBoard.IKapClose(m_pBoard);
IKapCLib.ItkDevClose(m_pDev);
}
return true;
}
private bool loadConfiguration(string sFilePath)
{
int ret = IKapBoard.IKapLoadConfigurationFromFile(m_pBoard, sFilePath);
return ret == (int)ErrorCode.IK_RTN_OK;
}
private bool createBuffer()
{
int ret = (int)ErrorCode.IK_RTN_OK;
int nImageType = 0;
ret = IKapBoard.IKapGetInfo(m_pBoard, (uint)INFO_ID.IKP_IMAGE_WIDTH, ref m_nWidth);
if (ret != (int)ErrorCode.IK_RTN_OK)
return false;
ret = IKapBoard.IKapGetInfo(m_pBoard, (uint)INFO_ID.IKP_IMAGE_HEIGHT, ref m_nHeight);
if (ret != (int)ErrorCode.IK_RTN_OK)
return false;
ret = IKapBoard.IKapGetInfo(m_pBoard, (uint)INFO_ID.IKP_IMAGE_TYPE, ref nImageType);
if (ret != (int)ErrorCode.IK_RTN_OK)
return false;
ret = IKapBoard.IKapGetInfo(m_pBoard, (uint)INFO_ID.IKP_DATA_FORMAT, ref m_nDepth);
if (ret != (int)ErrorCode.IK_RTN_OK)
return false;
ret = IKapBoard.IKapGetInfo(m_pBoard, (uint)INFO_ID.IKP_FRAME_SIZE, ref m_nBufferSize);
if (ret != (int)ErrorCode.IK_RTN_OK)
return false;
switch (nImageType)
{
case 0:
m_nChannels = 1;
break;
case 1:
case 3:
m_nChannels = 3;
break;
case 2:
case 4:
m_nChannels = 4;
break;
}
WarningEvent?.Invoke(DateTime.Now,WarningEnum.Normal, $"图片类型:{nImageType},通道数:{m_nChannels},size:{m_nWidth}*{m_nHeight}");
m_pUserBuffer = Marshal.AllocHGlobal(m_nBufferSize);
//
hBuffer = new BufferToImage(m_nBufferSize , m_nDepth, m_nChannels , m_nWidth, m_nHeight);
return true;
}
private void clearBuffer()
{
if (m_pUserBuffer == new IntPtr(-1))
return;
Marshal.FreeHGlobal(m_pUserBuffer);
m_pUserBuffer = new IntPtr(-1);
}
}
}