|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561 |
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- 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 LeatherApp.Interface;
- using Newtonsoft.Json.Linq;
- using OpenCvSharp;
- using OpenCvSharp.Dnn;
- using ErrorCode = IKapBoardClassLibrary.ErrorCode;
-
- namespace LeatherApp.Device
- {
- public class CamerCardDev2 : ABSCamerCardDev,IDisposable
- {
- [DllImport("user32.dll")]
- [return: MarshalAs(UnmanagedType.Bool)]
- private static extern bool IsWindow(IntPtr hWnd);
-
- [DllImport("kernel32.dll", EntryPoint = "RtlCopyMemory", SetLastError = false)]
- public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);
- [DllImport("User32.dll")]
- public extern static System.IntPtr GetDC(System.IntPtr hWnd);
-
- [DllImport("user32.dll")]
- private static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
-
- //显示图像控件句柄
- private PictureBox previewHwnd = null;
- //
- // 采集卡设备句柄。
- public IntPtr m_hBoard = new IntPtr(-1);
- // 当前帧索引。
- public int m_nCurFrameIndex = 0;
- // 图像缓冲区申请的帧数。
- public int m_nTotalFrameCount = 1;
- // 保存图像的文件名。
- public string m_strFileName = "C:\\CSharpImage.bmp";
-
- //
- private int scanIndex = 0; //实际拍照从1开始命名,因先加的1
- private string bmpSavePath;
-
-
- /// <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;//相机索引(一个采集卡上可插多个相机)
-
- public CamerCardDev2( )
- {
- }
- public override bool open(int cardIndex = 0,int scannerIndex = 0)
- {
- if (IsInit) return true;
-
- //m_stIFInfoList = _m_stIFInfoList;
- _scannerCardIndex = cardIndex;
- _scannerIndex = scannerIndex;
- System.GC.Collect();
- try
- {
- int ret = (int)ErrorCode.IK_RTN_OK;
- uint nPCIeDevCount = 0;
- StringBuilder resourceName;
- uint resourceNameSize = 0;
- IKapBoard.IKAPERRORINFO tIKei = new IKapBoard.IKAPERRORINFO();
-
- // 获取连接的采集卡数量。
- ret = IKapBoard.IKapGetBoardCount((int)BoardType.IKBoardPCIE, ref nPCIeDevCount);
- CheckIKapBoard(ret);
-
- // 当没有连接的采集卡时。
- if (nPCIeDevCount == 0 || nPCIeDevCount< cardIndex+1)
- {
- WarningEvent?.Invoke(WarningEnum.High, "Get board count 0");
- return false;
- }
-
- // 获取采集卡名称。
- for (uint i = 0; i < nPCIeDevCount; i++)
- {
- resourceNameSize = 0;
- resourceName = new StringBuilder(0);
- IKapBoard.IKapGetBoardName((uint)BoardType.IKBoardPCIE, i, resourceName, ref resourceNameSize);
- IKapBoard.IKapGetLastError(ref tIKei, true);
- if (tIKei.uErrorCode == (uint)ErrorCode.IKStatus_BufferTooSmall)
- {
- resourceName = new StringBuilder((int)resourceNameSize);
- IKapBoard.IKapGetBoardName((uint)BoardType.IKBoardPCIE, i, resourceName, ref resourceNameSize);
- }
- IKapBoard.IKapGetLastError(ref tIKei, true);
- if (tIKei.uErrorCode != (uint)ErrorCode.IKStatus_Success)
- {
- WarningEvent?.Invoke(WarningEnum.High, "Get Device Name Fail. Error Code:"+tIKei.uErrorCode);
- return false;
- }
- string sMesg = string.Concat("PCIE Device- ", i.ToString("d"), "\nName: ", resourceName);
-
- }
-
- // 打开采集卡。
- //
- // Open frame grabber.
- m_hBoard = IKapBoard.IKapOpen((int)BoardType.IKBoardPCIE, 0);//采集卡索引0-n
- if (m_hBoard.Equals(-1))
- {
- WarningEvent?.Invoke(WarningEnum.High, "Open device failure!");
- return false;
- }
-
- // 导入配置文件。
- string configFileName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\DevCfg\\"+ Config.CarmerConfigFilePath;
- if (!File.Exists(configFileName))
- {
- WarningEvent?.Invoke(WarningEnum.High, "Fail to get configuration, using default setting!");
- return false;
- }
- ret = IKapBoard.IKapLoadConfigurationFromFile(m_hBoard, configFileName);
- CheckIKapBoard(ret);
-
- // 设置图像缓冲区帧数。
- //
- // Set frame count of buffer.
- ret = IKapBoard.IKapSetInfo(m_hBoard, (uint)INFO_ID.IKP_FRAME_COUNT, m_nTotalFrameCount);
- CheckIKapBoard(ret);
-
- // 设置超时时间。
- //
- // Set time out time.
- int timeout = -1;
- ret = IKapBoard.IKapSetInfo(m_hBoard, (uint)INFO_ID.IKP_TIME_OUT, timeout);
- CheckIKapBoard(ret);
-
- // 设置采集模式。
- //
- // Set grab mode.
- int grab_mode = (int)GrabMode.IKP_GRAB_NON_BLOCK;//非阻塞StartGrab
- ret = IKapBoard.IKapSetInfo(m_hBoard, (uint)INFO_ID.IKP_GRAB_MODE, grab_mode);
- CheckIKapBoard(ret);
-
- // 设置传输模式。
- //
- // Set transfer mode.
- int transfer_mode = (int)FrameTransferMode.IKP_FRAME_TRANSFER_SYNCHRONOUS_NEXT_EMPTY_WITH_PROTECT;
- ret = IKapBoard.IKapSetInfo(m_hBoard, (uint)INFO_ID.IKP_FRAME_TRANSFER_MODE, transfer_mode);
- CheckIKapBoard(ret);
-
- // 注册回调函数
- //
- // Register callback functions.
- OnGrabStartProc = new IKapCallBackProc(OnGrabStartFunc);
- ret = IKapBoard.IKapRegisterCallback(m_hBoard, (uint)CallBackEvents.IKEvent_GrabStart, Marshal.GetFunctionPointerForDelegate(OnGrabStartProc), m_hBoard);
- CheckIKapBoard(ret);
- OnFrameReadyProc = new IKapCallBackProc(OnFrameReadyFunc);
- ret = IKapBoard.IKapRegisterCallback(m_hBoard, (uint)CallBackEvents.IKEvent_FrameReady, Marshal.GetFunctionPointerForDelegate(OnFrameReadyProc), m_hBoard);
- CheckIKapBoard(ret);
- OnFrameLostProc = new IKapCallBackProc(OnFrameLostFunc);
- ret = IKapBoard.IKapRegisterCallback(m_hBoard, (uint)CallBackEvents.IKEvent_FrameLost, Marshal.GetFunctionPointerForDelegate(OnFrameLostProc), m_hBoard);
- CheckIKapBoard(ret);
- OnTimeoutProc = new IKapCallBackProc(OnTimeoutFunc);
- ret = IKapBoard.IKapRegisterCallback(m_hBoard, (uint)CallBackEvents.IKEvent_TimeOut, Marshal.GetFunctionPointerForDelegate(OnTimeoutProc), m_hBoard);
- CheckIKapBoard(ret);
- OnGrabStopProc = new IKapCallBackProc(OnGrabStopFunc);
- ret = IKapBoard.IKapRegisterCallback(m_hBoard, (uint)CallBackEvents.IKEvent_GrabStop, Marshal.GetFunctionPointerForDelegate(OnGrabStopProc), m_hBoard);
- CheckIKapBoard(ret);
-
- // 设置行触发参数。
- //SetLineTrigger();
- //
- getParam();
-
- IsInit = true;
- //timer.Elapsed += Timer_Elapsed;
- //timer.Interval = 100;
- //timer.Enabled = true;
- return true;
- }
- catch (Exception ex)
- {
- WarningEvent?.Invoke(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;
-
- this.previewHwnd= preview_Hwnd;
- this.bmpSavePath = bmp_save_path;
- //开始采集
- //第二个参数 nFrameCount 表示希望 IKapBoardClassLibrary 采集的帧数。
- //如果 nFrameCount = 1,IKapBoardClassLibrary 会从相机中采集一帧图像;
- //如果 nFrameCount = N 且 N> 1,则 IKapBoardClassLibrary 从相机中采集连续的 N 帧图 像;
- //如果 nFrameCount = 0,则 IKapBoardClassLibrary 开始连续采集图像。
- var ret = IKapBoard.IKapStartGrab(m_hBoard, 0);
- return ret == (int)ErrorCode.IK_RTN_OK;
- }
- /// <summary>
- /// 停止采集
- /// </summary>
- public override void stop()
- {
- if (!IsInit) return;
-
- try
- {
- // 停止图像采集。
- var ret = IKapBoard.IKapStopGrab(m_hBoard);
- 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;
-
- //CParam cDeviceParam = new CParam(m_cInterface);
-
- //MV_FG_FLOATVALUE stParam=new MV_FG_FLOATVALUE();
- //int nRet = cDeviceParam.GetFloatValue("ExposureTime", ref stParam);
- //if (nRet == CErrorCode.MV_FG_SUCCESS) ExposureTime = stParam.fCurValue;
-
- //nRet = cDeviceParam.GetFloatValue("Gain", ref stParam);
- //if (nRet == CErrorCode.MV_FG_SUCCESS) Gain = stParam.fCurValue;
-
- //nRet = cDeviceParam.GetFloatValue("ResultingFrameRate", ref stParam);
- //if (nRet == CErrorCode.MV_FG_SUCCESS) ResultingFrameRate = stParam.fCurValue;
- }
- /// <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;
- //CParam cDeviceParam = new CParam(m_cInterface);
- //int nRet;
- //if (exposureTime != ExposureTime && exposureTime != -1)
- //{
- // nRet = cDeviceParam.SetEnumValue("ExposureAuto", (uint)0);
- // if (CErrorCode.MV_FG_SUCCESS != nRet)
- // WarningEvent?.Invoke(WarningEnum.Low, "ExposureTime SetEnumValue(\"ExposureAuto\") res=" + nRet);
- // nRet = cDeviceParam.SetFloatValue("ExposureTime", exposureTime);
- // if (CErrorCode.MV_FG_SUCCESS != nRet)
- // WarningEvent?.Invoke(WarningEnum.Low, "ExposureTime SetFloatValue(\"ExposureTime\") res=" + nRet);
- // change = true;
- //}
-
- //if (gain != Gain && gain != -1)
- //{
- // //device.MV_CC_SetEnumValue_NET("GainAuto", 0);
- // //nRet = device.MV_CC_SetFloatValue_NET("Gain", gain);
- // cDeviceParam.SetEnumValue("GainAuto", (uint)0);
- // cDeviceParam.SetFloatValue("Gain", gain);
- // 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_hBoard, (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_hBoard, (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_hBoard, (uint)CallBackEvents.IKEvent_GrabStart);
- ret = IKapBoard.IKapUnRegisterCallback(m_hBoard, (uint)CallBackEvents.IKEvent_FrameReady);
- ret = IKapBoard.IKapUnRegisterCallback(m_hBoard, (uint)CallBackEvents.IKEvent_FrameLost);
- ret = IKapBoard.IKapUnRegisterCallback(m_hBoard, (uint)CallBackEvents.IKEvent_TimeOut);
- ret = IKapBoard.IKapUnRegisterCallback(m_hBoard, (uint)CallBackEvents.IKEvent_GrabStop);
- }
-
- /* @brief:关闭设备。
- *
- * @brief:Close device. */
- private void CloseDevice()
- {
- // 关闭采集卡设备。
- //
- // Close frame grabber device.
- if (!m_hBoard.Equals(-1))
- {
- IKapBoard.IKapClose(m_hBoard);
- m_hBoard = (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)
- {
- Console.WriteLine("Start grabbing image");
- }
-
- /* @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)
- {
- Console.WriteLine("Image frame lost");
- }
-
- /* @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)
- {
- Console.WriteLine("Grab image timeout");
- }
-
- /* @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)
- {
- Console.WriteLine("Grab frame ready");
-
- IntPtr hDev = (IntPtr)pParam;
- IntPtr pUserBuffer = IntPtr.Zero;
- int nFrameSize = 0;
- int nFrameCount = 0;
- IKapBoard.IKAPBUFFERSTATUS status = new IKapBoard.IKAPBUFFERSTATUS();
-
- IKapBoard.IKapGetInfo(hDev, (uint)INFO_ID.IKP_FRAME_COUNT, ref nFrameCount);
- IKapBoard.IKapGetBufferStatus(hDev, m_nCurFrameIndex, ref status);
-
- // 当图像缓冲区满时。
- //
- // When the buffer is full.
- if (status.uFull == 1)
- {
- // 获取一帧图像的大小。
- //
- // Get the size of a frame of image.
- IKapBoard.IKapGetInfo(hDev, (uint)INFO_ID.IKP_FRAME_SIZE, ref nFrameSize);
-
- // 获取缓冲区地址。
- //
- // Get the buffer address.
- IKapBoard.IKapGetBufferAddress(hDev, m_nCurFrameIndex, ref pUserBuffer);
-
- // === 保存图像。
- //存文件
- //IKapBoard.IKapSaveBuffer(hDev, m_nCurFrameIndex, m_strFileName, (int)ImageCompressionFalg.IKP_DEFAULT_COMPRESSION);
- // 存到byte[]
- byte[] imageBuff = new byte[nFrameSize]; // 创建字节数组
- Marshal.Copy(pUserBuffer, imageBuff, 0, imageBuff.Length); // 将目标内存空间中的数据复制到结果字节数组
- //存到地址
- //IntPtr m_pDataBuf = Marshal.AllocHGlobal(nFrameSize); //分配空间
- //CopyMemory(m_pDataBuf, pUserBuffer, (uint)nFrameSize);
- //pictureBox1显示
- if (this.previewHwnd != null && IsWindow(this.previewHwnd.Handle))
- {
- this.previewHwnd.Image = bytes2bmp(imageBuff);
- }
-
- }
- m_nCurFrameIndex++;
- m_nCurFrameIndex = m_nCurFrameIndex % m_nTotalFrameCount;
- }
-
- /* @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;
- }
- }
- }
|