|
- 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 = 1,IKapBoardClassLibrary 会从相机中采集一帧图像;
- //如果 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:设置行触发参数。
- *
- * @brief:Set 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:清除回调函数。
- *
- * @brief:Unregister 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:关闭设备。
- *
- * @brief:Close 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:函数返回值。
- *
- * @brief:Determine whether the IKapBoard function is called successfully.
- * @param[in] ret:Function 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:本函数被注册为一个回调函数。当图像采集开始时,函数被调用。
- *
- * @brief:This function is registered as a callback function. When starting grabbing images, the function will be called. */
- private IKapCallBackProc OnGrabStartProc;
-
- /* @brief:本函数被注册为一个回调函数。当采集丢帧时,函数被调用。
- *
- * @brief:This function is registered as a callback function. When grabbing frame lost, the function will be called. */
- private IKapCallBackProc OnFrameLostProc;
-
- /* @brief:本函数被注册为一个回调函数。当图像采集超时时,函数被调用。
- *
- * @brief:This function is registered as a callback function. When grabbing images time out, the function will be called. */
- private IKapCallBackProc OnTimeoutProc;
-
- /* @brief:本函数被注册为一个回调函数。当一帧图像采集完成时,函数被调用。
- *
- * @brief:This function is registered as a callback function. When a frame of image grabbing ready, the function will be called. */
- private IKapCallBackProc OnFrameReadyProc;
-
- /* @brief:本函数被注册为一个回调函数。当图像采集停止时,函数被调用。
- *
- * @brief:This 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:输入参数。
- *
- * @brief:This function is registered as a callback function. When starting grabbing images, the function will be called.
- * @param[in] pParam:Input parameter. */
- public void OnGrabStartFunc(IntPtr pParam)
- {
- WarningEvent?.BeginInvoke(DateTime.Now,WarningEnum.Normal, "图像开始采集...", null, null);
- }
-
- /* @brief:本函数被注册为一个回调函数。当采集丢帧时,函数被调用。
- * @param[in] pParam:输入参数。
- *
- * @brief:This function is registered as a callback function. When grabbing frame lost, the function will be called.
- * @param[in] pParam:Input parameter. */
- public void OnFrameLostFunc(IntPtr pParam)
- {
- WarningEvent?.BeginInvoke(DateTime.Now,WarningEnum.High, $"相机({_scannerCardIndex})采集图像({scanIndex})丢帧(Image frame lost),急停告警,需结束重新开始!!!!", null, null);
- }
-
- /* @brief:本函数被注册为一个回调函数。当图像采集超时时,函数被调用。
- * @param[in] pParam:输入参数。
- *
- * @brief:This function is registered as a callback function. When grabbing images time out, the function will be called.
- * @param[in] pParam:Input parameter. */
- public void OnTimeoutFunc(IntPtr pParam)
- {
- WarningEvent?.BeginInvoke(DateTime.Now,WarningEnum.High, $"相机({_scannerCardIndex})采集图像({scanIndex})超时(Grab image timeout),请检查采集卡!", null, null);
- }
-
- /* @brief:本函数被注册为一个回调函数。当一帧图像采集完成时,函数被调用。
- * @param[in] pParam:输入参数。
- *
- * @brief:This function is registered as a callback function. When a frame of image grabbing ready, the function will be called.
- * @param[in] pParam:Input 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;
-
- var bmp = hBuffer.toBmp(m_pUserBuffer);
- Mat mat = OpenCvSharp.Extensions.BitmapConverter.ToMat(bmp);
- bmp.Dispose();
- bmp = null;
- //Monitor.Enter(frameQueue);
- lock (frameQueue)
- frameQueue.Enqueue(new MyData(index, mat));
- 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:输入参数。
- *
- * @brief:This function is registered as a callback function. When stopping grabbing images, the function will be called.
- * @param[in] pParam:Input 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);
- }
- }
- }
|