天天看点

C#采集海康相机图片hWindowControl显示

海康采图Demo

    • 准备资料
    • 代码流程分析
    • 成果展示

#为中华工控崛起而开源

欢迎各位老铁一起交流 微信号:V1ncent-xuan。

准备资料

项目 Value
项目依赖项 halcon、halcondotnet、MvCameraControl.Net
软件VS2019 链接: link.
海康MVS 链接: link.

代码流程分析

  • 1:UI设计
    C#采集海康相机图片hWindowControl显示
  • 2:定义程序变量
private MyCamera m_Camera;
public MyCamera.cbOutputExdelegate ImageCallback;

private ManualResetEvent m_autoEvent = new ManualResetEvent(false);
private ConcurrentQueue<HImage> m_queImage = new ConcurrentQueue<HImage>();
private HWindow m_hWnd;
           
  • 3:程序方法
  • 按钮1:枚举、创建、打开、探测、图片尺寸、设置参数、开启抓图
private void button1_Click_1(object sender, EventArgs e)
       {
           MyCamera.MV_CC_DEVICE_INFO_LIST stDevList = new MyCamera.MV_CC_DEVICE_INFO_LIST();
           int nRet = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref stDevList);
           if (MyCamera.MV_OK != nRet)
           {
               Log(string.Format("HikVision Enum device failed:{0:x8}", nRet));
               return;
           }

           if (stDevList.nDeviceNum<=0)
           {
               Log("枚举设备失败");
               return;
           }
           MyCamera.MV_CC_DEVICE_INFO stDevInfo;
           stDevInfo = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(stDevList.pDeviceInfo[0], typeof(MyCamera.MV_CC_DEVICE_INFO));

           string strDeviceName = string.Empty;
           if (MyCamera.MV_GIGE_DEVICE == stDevInfo.nTLayerType)
           {
               MyCamera.MV_GIGE_DEVICE_INFO stGigEDeviceInfo = (MyCamera.MV_GIGE_DEVICE_INFO)MyCamera.ByteToStruct(stDevInfo.SpecialInfo.stGigEInfo, typeof(MyCamera.MV_GIGE_DEVICE_INFO));
               uint nIp1 = ((stGigEDeviceInfo.nCurrentIp & 0xff000000) >> 24);
               uint nIp2 = ((stGigEDeviceInfo.nCurrentIp & 0x00ff0000) >> 16);
               uint nIp3 = ((stGigEDeviceInfo.nCurrentIp & 0x0000ff00) >> 8);
               uint nIp4 = (stGigEDeviceInfo.nCurrentIp & 0x000000ff);
               //Console.WriteLine("\n" + i.ToString() + ": [GigE] User Define Name : " + stGigEDeviceInfo.chUserDefinedName);
               strDeviceName = nIp1 + "." + nIp2 + "." + nIp3 + "." + nIp4;
               Log($"打开相机IP:{strDeviceName}");
           }
           m_Camera = new MyCamera();
           Log($"创建设备");
           nRet = m_Camera.MV_CC_CreateDevice_NET(ref stDevInfo);
           if (MyCamera.MV_OK != nRet)
           {            
               return ;
           }

           // ch:打开设备 | en:Open device
           Log($"打开设备");
           nRet = m_Camera.MV_CC_OpenDevice_NET();
           if (MyCamera.MV_OK != nRet)
           {
               Log($"打开设备失败");
               return ;
           }
           Log($"探测网络最佳包");
           // ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal package size(It only works for the GigE camera)
           if (stDevInfo.nTLayerType == MyCamera.MV_GIGE_DEVICE)
           {
               int nPacketSize = m_Camera.MV_CC_GetOptimalPacketSize_NET();
               if (nPacketSize > 0)
               {
                   Log($"nPacketSize>0");
                   nRet = m_Camera.MV_CC_SetIntValue_NET("GevSCPSPacketSize", (uint)nPacketSize);
                   if (nRet != MyCamera.MV_OK)
                   {
                   }
               }
               else
               {
                   Log($"nPacketSize<0");
               }
           }
           Log($"获取包大小");
           // ch:获取包大小 || en: Get Payload Size
           MyCamera.MVCC_INTVALUE stParam = new MyCamera.MVCC_INTVALUE();
           nRet = m_Camera.MV_CC_GetIntValue_NET("PayloadSize", ref stParam);
           if (MyCamera.MV_OK != nRet)
           {
               //LogHelper.Warn(string.Format("Warning: Get PayloadSize failed {0:x8}", nRet));
           }

           int width = 0, height = 0;//创建变量用于接收图像尺寸
     
           nRet = m_Camera.MV_CC_GetIntValue_NET("HeightMax", ref stParam);
           height= (int)stParam.nCurValue;
           nRet = m_Camera.MV_CC_GetIntValue_NET("WidthMax", ref stParam);
           width = (int)stParam.nCurValue;
           m_hWnd.SetPart(0, 0, height - 1, width - 1);//设置Halcon控件中图像的显示尺寸

           // ch:设置采集连续模式 | en:Set Continues Aquisition Mode
           Log($"设置连续采集2");
           nRet = m_Camera.MV_CC_SetEnumValue_NET("AcquisitionMode", (uint)MyCamera.MV_CAM_ACQUISITION_MODE.MV_ACQ_MODE_CONTINUOUS);
           Log($"触发模式1");
           nRet = m_Camera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON);

           //软触发
           Log($"软触发7");
           nRet = m_Camera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE);

           // ch:注册回调函数 | en:Register image callback
           ImageCallback = new MyCamera.cbOutputExdelegate(OnImageGrabbed);
           nRet = m_Camera.MV_CC_RegisterImageCallBackEx_NET(ImageCallback, IntPtr.Zero);

           // ch:开启抓图 || en: start grab image
           nRet = m_Camera.MV_CC_StartGrabbing_NET();

       }
           
  • 按钮2:采图
private void button2_Click(object sender, EventArgs e)
        {
            // ch:触发命令 | en:Trigger command
            int nRet = m_Camera.MV_CC_SetCommandValue_NET("TriggerSoftware");
            Log("软触发一次");
        }
           
  • 3:采图窗体加载显示Handler图片线程。
private void Form1_Load(object sender, EventArgs e)
        {
            Thread thread = new Thread(ThreadProc);
            thread.IsBackground = true;
            thread.Start(m_queImage);

            m_hWnd = this.hWindowControl1.HalconWindow;
        }
private void ThreadProc( object obj)
        {
            //图片在队列 随便怎么处理。算法下期见!
            ConcurrentQueue<HImage> queImage = obj as ConcurrentQueue<HImage>;      
            HImage image1 = new HImage();
            while (true)
            {
                m_autoEvent.WaitOne();
                if (queImage.Count>0)
                {                 
                   queImage.TryDequeue(out image1);
                   //添加处理图像方法
                   //XXX
                   //最后显示
                    ShowImage(image1);
                    
                }
                Thread.Sleep(100);
            }
        }

public void ShowImage( HImage image)
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke((MethodInvoker)delegate
                {
                    ShowImage( image);
                });
            }
            else
            {            
                HSystem.SetSystem("flush_graphic", "false");
                m_hWnd.ClearWindow();
                m_hWnd.DispObj(image);
                HSystem.SetSystem("flush_graphic", "true");
                m_hWnd.SetColor("black");
                m_hWnd.DispLine(-100.0, -100.0, -101.0, -101.0);
            }     
        }
           

4 按钮2点击,采图后进入回调。

private void OnImageGrabbed(IntPtr pData, ref MyCamera.MV_FRAME_OUT_INFO_EX pFrameInfo, IntPtr pUser)
        {

            Log("Get one frame: Width[" + Convert.ToString(pFrameInfo.nWidth) + "] , Height[" + Convert.ToString(pFrameInfo.nHeight)
                                + "] , FrameNum[" + Convert.ToString(pFrameInfo.nFrameNum) + "]");
            HImage image = new HImage();
            int nWidth = pFrameInfo.nWidth;
            int nHeight = pFrameInfo.nHeight;
           
            IntPtr pTemp = IntPtr.Zero;
            pTemp = pData;
            image.GenImage1Extern("byte", nWidth, nHeight, pTemp, IntPtr.Zero);

            //防止一直采集把内存占满
            if (m_queImage.Count > 5)
            {
                HImage temp;
                m_queImage.TryDequeue(out temp);
            }

            m_queImage.Enqueue(image);
            m_autoEvent.Set();
        }
           
  1. 窗体关闭进行 资源关闭
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (m_Camera!=null)
            {
                int nRet = m_Camera.MV_CC_StopGrabbing_NET();

                // ch:关闭设备 | en:Close device
                nRet = m_Camera.MV_CC_CloseDevice_NET();

                // ch:销毁设备 | en:Destroy device
                nRet = m_Camera.MV_CC_DestroyDevice_NET();
            }
            

            m_Camera = null;
        }
           

成果展示

C#采集海康相机图片hWindowControl显示
C#采集海康相机图片hWindowControl显示
C#采集海康相机图片hWindowControl显示

继续阅读