VisionPro的实时画面显示的两种方法

一、通过VisionPro工具进行连续运行,不断的获取最终的结果实现实时画面;

1.1 VisionPro的自带工具

使用VisionPro工具获取实时画面是比较取巧的一种方式,不需要很复杂的代码即可实现,主要是通过运行VisionPro程序来或得结果,从而达到我们需要的画面,VisionPro里面自己携带了一个工具,名称:CogAcqFifoTool,这个工具是可以直接连接相机并可进行各种属性的保存,比如相机的曝光,增益等;

1.2 代码实现

如果只是获取实时画面在Toolblock里面添加这一个工具即可,然后在二次开发时,加载这个Toolblock的程序,再获取到CogAcqFifoTool工具的输出画面即可;

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Cognex.VisionPro;
using Cognex.VisionPro.ToolBlock;

namespace Camera_Live
{
    public partial class Form1 : Form
    {
        CogToolBlock toolBlock;//定义一个Toolblock变量


        public Form1()
        {
            InitializeComponent();
        }
        /// <summary>
        /// 实时画面的显示,打开相机
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OpenCamera_CheckedChanged(object sender, EventArgs e)
        {
            //1.加载Toolblock工具,需要包含有CogAcqFifoTool工具的程序
             toolBlock = (CogToolBlock)CogSerializer.LoadObjectFromFile(vppPath.Text);
            //2.获取到Vpp程序内的CogAcqFifoTool工具
            CogAcqFifoTool fifoTool = toolBlock.Tools["CogAcqFifoTool1"] as CogAcqFifoTool;
            //使用线程循环运行取得实时图像
            Task.Run(() =>
            {
                do
                {
                    //3.运行工具
                    fifoTool.Run();
                    //4.将工具的输出图片给显示的控件上
                    cogRecordDisplay1.Image = fifoTool.OutputImage;
                    //5.图像适应控件在中央
                    cogRecordDisplay1.AutoFit = true;
                } while (OpenCamera.Checked);
            });
        }
        /// <summary>
        /// 关闭相机
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CloseCamera_CheckedChanged(object sender, EventArgs e)
        {
            toolBlock.Dispose();
        }
    }
}

这里面我使用了两个radiobutton来实现了重复的运行CogAcqFifoTool,从而得到自己的实时画面;

1.3 USB3.0相机的实现方法

当然这是VisionPro自带的工具,这个工具主要还是针对的是网口的相机,像海康,大华,Balser等大牌都可以使用,但此工具不支持USB3.0的相机,而现在USB接口相机也比较的常用,那该怎么办呢?海康这边非常的照顾客户给我们提供了相应的工具,

按照文档提供的方法即可将工具添加进去了,使用方法和上面一样;在程序中使用这个工具是这样子的:

 MvCameraAcqTool.MvCameraAcqTool mvCameraAcq;//相机变量

是不是很简单,哈哈!!! 

二、通过相机的SDK开发从而实现实时画面;

2.1 SDK开发流程

这里就主要以海康相机SDK开发做介绍了,其他相机的大家根据各自的SDK说明开发就可以了。我们先来看下海康SDK开发文档的编程引导:

先要通过枚举的方式找到对应设备,在创建设备,打开设备,开始取流,后面可以传递给VisionPro控件;

2.2 代码实现

首先是枚举设备

 /// <summary>
 /// 枚举相机
 /// </summary>
 private void DeviceListAcq()
 {
     int nRet;
     // ch:创建设备列表 || en: Create device list
     System.GC.Collect();
     //获取相机的列表,包含网口和U口相机
     nRet = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref m_pDeviceList);
     if (MyCamera.MV_OK != nRet)
     {
         MessageBox.Show("Enum Devices Fail");
         return;
     }
 }

其次是打开设备 

 /// <summary>
 /// 打开设备
 /// </summary>
 private void OpenCamera()
 {
     //判断是否有相机
     if (m_pDeviceList.nDeviceNum == 0)
     {
         MessageBox.Show("No device,please select");
         return;
     }
     //这里选择了第一个相机
     MyCamera.MV_CC_DEVICE_INFO device =
         (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(m_pDeviceList.pDeviceInfo[0],
                                                       typeof(MyCamera.MV_CC_DEVICE_INFO));
     int nRet = -1;
     m_pMyCamera = new MyCamera();
     //获取设备信息
     nRet = m_pMyCamera.MV_CC_CreateDevice_NET(ref device);
     if (MyCamera.MV_OK != nRet)
     {
         return;
     }

     // ch:打开设备 | en:Open device
     nRet = m_pMyCamera.MV_CC_OpenDevice_NET();
     if (MyCamera.MV_OK != nRet)
     {
         MessageBox.Show("Open Device Fail");
         return;
     }

     // ch:获取包大小 || en: Get Payload Size
     MyCamera.MVCC_INTVALUE_EX stParam = new MyCamera.MVCC_INTVALUE_EX();
     nRet = m_pMyCamera.MV_CC_GetIntValueEx_NET("PayloadSize", ref stParam);
     if (MyCamera.MV_OK != nRet)
     {
         MessageBox.Show("Get PayloadSize Fail");
         return;
     }
     g_nPayloadSize = (uint)stParam.nCurValue;

     // ch:获取高 || en: Get Height
     nRet = m_pMyCamera.MV_CC_GetIntValueEx_NET("Height", ref stParam);
     if (MyCamera.MV_OK != nRet)
     {
         MessageBox.Show("Get Height Fail");
         return;
     }
     uint nHeight = (uint)stParam.nCurValue;

     // ch:获取宽 || en: Get Width
     nRet = m_pMyCamera.MV_CC_GetIntValueEx_NET("Width", ref stParam);
     if (MyCamera.MV_OK != nRet)
     {
         MessageBox.Show("Get Width Fail");
         return;
     }
     uint nWidth = (uint)stParam.nCurValue;

     // ch:获取步长 || en: Get nRowStep
     m_nRowStep = nWidth * nHeight;
 }

然后就是取流了 

 /// <summary>
 /// 开始采图
 /// </summary>
 private void StartGrab()
 {
     int nRet;
     // ch:开启抓图 | en:start grab
     nRet = m_pMyCamera.MV_CC_StartGrabbing_NET();
     if (MyCamera.MV_OK != nRet)
     {
         MessageBox.Show("Start Grabbing Fail");
         return;
     }
     m_bGrabbing = true;
     Thread hReceiveImageThreadHandle = new Thread(ReceiveImageWorkThread);
     hReceiveImageThreadHandle.Start(m_pMyCamera);
     //软触发
     m_pMyCamera.MV_CC_SetEnumValue_NET("TriggerSource", 7);
 }

相机的图片的黑白和彩色的判断

  #region  判断图片是黑白还是彩色
  /// <summary>
  /// 图像是否为Mono格式
  /// </summary>
  /// <param name="enType"></param>
  /// <returns></returns>
  private bool IsMonoPixelFormat(MyCamera.MvGvspPixelType enType)
  {
      switch (enType)
      {
          case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8:
          case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono10:
          case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono10_Packed:
          case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono12:
          case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono12_Packed:
              return true;
          default:
              return false;
      }
  }

  /// <summary>
  /// 图像是否为彩色
  /// </summary>
  /// <param name="enType"></param>
  /// <returns></returns>
  private bool IsColorPixelFormat(MyCamera.MvGvspPixelType enType)
  {
      switch (enType)
      {
          case MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed:
          case MyCamera.MvGvspPixelType.PixelType_Gvsp_BGR8_Packed:
          case MyCamera.MvGvspPixelType.PixelType_Gvsp_RGBA8_Packed:
          case MyCamera.MvGvspPixelType.PixelType_Gvsp_BGRA8_Packed:
          case MyCamera.MvGvspPixelType.PixelType_Gvsp_YUV422_Packed:
          case MyCamera.MvGvspPixelType.PixelType_Gvsp_YUV422_YUYV_Packed:
          case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR8:
          case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG8:
          case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB8:
          case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG8:
          case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB10:
          case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB10_Packed:
          case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG10:
          case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG10_Packed:
          case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG10:
          case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG10_Packed:
          case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR10:
          case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR10_Packed:
          case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB12:
          case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB12_Packed:
          case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG12:
          case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG12_Packed:
          case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG12:
          case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG12_Packed:
          case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR12:
          case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR12_Packed:
              return true;
          default:
              return false;
      }
  }

  /// <summary>
  /// 其他黑白格式转为Mono8
  /// </summary>
  /// <param name="obj"></param>
  /// <param name="pInData">输出图片数据</param>
  /// <param name="pOutData">输出图片数据</param>
  /// <param name="nHeight">高</param>
  /// <param name="nWidth">宽</param>
  /// <param name="nPixelType">像素格式</param>
  /// <returns></returns>
  public Int32 ConvertToMono8(object obj, IntPtr pInData, IntPtr pOutData, ushort nHeight, ushort nWidth, MyCamera.MvGvspPixelType nPixelType)
  {
      if (IntPtr.Zero == pInData || IntPtr.Zero == pOutData)
      {
          return MyCamera.MV_E_PARAMETER;
      }

      int nRet = MyCamera.MV_OK;
      MyCamera device = obj as MyCamera;
      MyCamera.MV_PIXEL_CONVERT_PARAM stPixelConvertParam = new MyCamera.MV_PIXEL_CONVERT_PARAM();

      stPixelConvertParam.pSrcData = pInData;//源数据
      if (IntPtr.Zero == stPixelConvertParam.pSrcData)
      {
          return -1;
      }

      stPixelConvertParam.nWidth = nWidth;//图像宽度
      stPixelConvertParam.nHeight = nHeight;//图像高度
      stPixelConvertParam.enSrcPixelType = nPixelType;//源数据的格式
      stPixelConvertParam.nSrcDataLen = (uint)(nWidth * nHeight * ((((uint)nPixelType) >> 16) & 0x00ff) >> 3);

      stPixelConvertParam.nDstBufferSize = (uint)(nWidth * nHeight * ((((uint)MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed) >> 16) & 0x00ff) >> 3);
      stPixelConvertParam.pDstBuffer = pOutData;//转换后的数据
      stPixelConvertParam.enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8;
      stPixelConvertParam.nDstBufferSize = (uint)(nWidth * nHeight * 3);

      nRet = device.MV_CC_ConvertPixelType_NET(ref stPixelConvertParam);//格式转换
      if (MyCamera.MV_OK != nRet)
      {
          return -1;
      }

      return nRet;
  }

  /// <summary>
  /// 其他彩色格式转为RGB8
  /// </summary>
  /// <param name="obj"></param>
  /// <param name="pSrc"></param>
  /// <param name="nHeight"></param>
  /// <param name="nWidth"></param>
  /// <param name="nPixelType"></param>
  /// <param name="pDst"></param>
  /// <returns></returns>
  public Int32 ConvertToRGB(object obj, IntPtr pSrc, ushort nHeight, ushort nWidth, MyCamera.MvGvspPixelType nPixelType, IntPtr pDst)
  {
      if (IntPtr.Zero == pSrc || IntPtr.Zero == pDst)
      {
          return MyCamera.MV_E_PARAMETER;
      }

      int nRet = MyCamera.MV_OK;
      MyCamera device = obj as MyCamera;
      MyCamera.MV_PIXEL_CONVERT_PARAM stPixelConvertParam = new MyCamera.MV_PIXEL_CONVERT_PARAM();

      stPixelConvertParam.pSrcData = pSrc;//源数据
      if (IntPtr.Zero == stPixelConvertParam.pSrcData)
      {
          return -1;
      }

      stPixelConvertParam.nWidth = nWidth;//图像宽度
      stPixelConvertParam.nHeight = nHeight;//图像高度
      stPixelConvertParam.enSrcPixelType = nPixelType;//源数据的格式
      stPixelConvertParam.nSrcDataLen = (uint)(nWidth * nHeight * ((((uint)nPixelType) >> 16) & 0x00ff) >> 3);

      stPixelConvertParam.nDstBufferSize = (uint)(nWidth * nHeight * ((((uint)MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed) >> 16) & 0x00ff) >> 3);
      stPixelConvertParam.pDstBuffer = pDst;//转换后的数据
      stPixelConvertParam.enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed;
      stPixelConvertParam.nDstBufferSize = (uint)nWidth * nHeight * 3;

      nRet = device.MV_CC_ConvertPixelType_NET(ref stPixelConvertParam);//格式转换
      if (MyCamera.MV_OK != nRet)
      {
          return -1;
      }

      return MyCamera.MV_OK;
  }
  #endregion

接收图片数据的函数,显示图片

 /// <summary>
 /// 显示图片
 /// </summary>
 /// <param name="nHeight">高</param>
 /// <param name="nWidth">宽</param>
 /// <param name="pImageBuf">图片数据</param>
 /// <param name="enPixelType">像素格式</param>
 public void VisionProDisplay(UInt32 nHeight, UInt32 nWidth, IntPtr pImageBuf, MyCamera.MvGvspPixelType enPixelType)
 {
     // ch: 显示 || display
     try
     {
         //黑白图片
         if (enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8)
         {
             CogImage8Root cogImage8Root = new CogImage8Root();
             cogImage8Root.Initialize((Int32)nWidth, (Int32)nHeight, pImageBuf, (Int32)nWidth, null);
             //图像的转换
             CogImage8Grey cogImage8Grey = new CogImage8Grey();
             cogImage8Grey.SetRoot(cogImage8Root);
             //显示图片
             this.cogRecordDisplay1.Image = cogImage8Grey.ScaleImage((int)nWidth, (int)nHeight);
             this.cogRecordDisplay1.AutoFit = true;
             System.GC.Collect();
         }
         else  //彩色图片
         {
             CogImage8Root image0 = new CogImage8Root();
             IntPtr ptr0 = new IntPtr(pImageBuf.ToInt64());
             image0.Initialize((int)nWidth, (int)nHeight, ptr0, (int)nWidth, null);

             CogImage8Root image1 = new CogImage8Root();
             IntPtr ptr1 = new IntPtr(pImageBuf.ToInt64() + m_nRowStep);
             image1.Initialize((int)nWidth, (int)nHeight, ptr1, (int)nWidth, null);

             CogImage8Root image2 = new CogImage8Root();
             IntPtr ptr2 = new IntPtr(pImageBuf.ToInt64() + m_nRowStep * 2);
             image2.Initialize((int)nWidth, (int)nHeight, ptr2, (int)nWidth, null);
             
             CogImage24PlanarColor colorImage = new CogImage24PlanarColor();
             colorImage.SetRoots(image0, image1, image2);

             this.cogRecordDisplay1.Image = colorImage.ScaleImage((int)nWidth, (int)nHeight);
             this.cogRecordDisplay1.AutoFit = true;
             System.GC.Collect();
         }
     }
     catch (System.Exception ex)
     {
         MessageBox.Show(ex.ToString());
         return;
     }
     return;
 }
 /// <summary>
 /// 接收图片线程函数
 /// </summary>
 /// <param name="obj"></param>
 public void ReceiveImageWorkThread(object obj)
 {
     int nRet = MyCamera.MV_OK;
     MyCamera device = obj as MyCamera;
     MyCamera.MV_FRAME_OUT_INFO_EX pFrameInfo = new MyCamera.MV_FRAME_OUT_INFO_EX();
     IntPtr pData = Marshal.AllocHGlobal((int)g_nPayloadSize);
     if (pData == IntPtr.Zero)
     {
         return;
     }
     IntPtr pImageBuffer = Marshal.AllocHGlobal((int)m_nRowStep * 3);
     if (pImageBuffer == IntPtr.Zero)
     {
         return;
     }

     IntPtr pTemp = IntPtr.Zero;
     Byte[] byteArrImageData = new Byte[m_nRowStep * 3];

     while (m_bGrabbing)
     {
         nRet = device.MV_CC_GetOneFrameTimeout_NET(pData, g_nPayloadSize, ref pFrameInfo, 1000);
         if (MyCamera.MV_OK == nRet)
         {
             MyCamera.MvGvspPixelType pixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed;
             if (IsColorPixelFormat(pFrameInfo.enPixelType))    // 彩色图像处理
             {
                 if (pFrameInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed)
                 {
                     pTemp = pData;
                 }
                 else
                 {
                     // 其他格式彩色图像转为RGB
                     nRet = ConvertToRGB(obj, pData, pFrameInfo.nHeight, pFrameInfo.nWidth, pFrameInfo.enPixelType, pImageBuffer);
                     if (MyCamera.MV_OK != nRet)
                     {
                         return;
                     }
                     pTemp = pImageBuffer;
                 }

                 // Packed转Plane
                 unsafe
                 {
                     byte* pBufForSaveImage = (byte*)pTemp;

                     UInt32 nSupWidth = (pFrameInfo.nWidth + (UInt32)3) & 0xfffffffc;

                     for (int nRow = 0; nRow < pFrameInfo.nHeight; nRow++)
                     {
                         for (int col = 0; col < pFrameInfo.nWidth; col++)
                         {
                             byteArrImageData[nRow * nSupWidth + col] = pBufForSaveImage[nRow * pFrameInfo.nWidth * 3 + (3 * col)];
                             byteArrImageData[pFrameInfo.nWidth * pFrameInfo.nHeight + nRow * nSupWidth + col] = pBufForSaveImage[nRow * pFrameInfo.nWidth * 3 + (3 * col + 1)];
                             byteArrImageData[pFrameInfo.nWidth * pFrameInfo.nHeight * 2 + nRow * nSupWidth + col] = pBufForSaveImage[nRow * pFrameInfo.nWidth * 3 + (3 * col + 2)];
                         }
                     }
                     pTemp = Marshal.UnsafeAddrOfPinnedArrayElement(byteArrImageData, 0);
                 }
             }
             else if (IsMonoPixelFormat(pFrameInfo.enPixelType))    // Mono图像处理
             {
                 if (pFrameInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8)
                 {
                     pTemp = pData;
                 }
                 else
                 {
                     // 其他格式Mono转为Mono8
                     nRet = ConvertToMono8(device, pData, pImageBuffer, pFrameInfo.nHeight, pFrameInfo.nWidth, pFrameInfo.enPixelType);
                     if (MyCamera.MV_OK != nRet)
                     {
                         return;
                     }
                     pTemp = pImageBuffer;
                 }
                 pixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8;
             }
             else
             {
                 continue;
             }
             VisionProDisplay(pFrameInfo.nHeight, pFrameInfo.nWidth, pTemp, pixelType);
         }
         else
         {
             continue;
         }
     }
     if (pData != IntPtr.Zero)
     {
         Marshal.FreeHGlobal(pData);
     }
     if (pImageBuffer != IntPtr.Zero)
     {
         Marshal.FreeHGlobal(pImageBuffer);
     }
     return;
 }

最后是关闭相机

 /// <summary>
 /// 关闭设备
 /// </summary>
 private void CloseCamera()
 {

     if (m_bGrabbing)
     {
         m_bGrabbing = false;
         // ch:停止抓图 || en:Stop grab image
         m_pMyCamera.MV_CC_StopGrabbing_NET();
     }
     // ch:关闭设备 || en: Close device
     m_pMyCamera.MV_CC_CloseDevice_NET();
     m_pMyCamera.MV_CC_DestroyDevice_NET();
     m_bGrabbing = false;
    

 }
2.3 代码源码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Media.Media3D;
using Cognex.VisionPro;
using MvCamCtrl.NET;


namespace CamerHiK
{
    public partial class Camera : Form
    {
        #region 参数
        MyCamera.MV_CC_DEVICE_INFO_LIST m_pDeviceList; //相机列表
        private MyCamera m_pMyCamera;
        bool m_bGrabbing;

        UInt32 g_nPayloadSize = 0;
        UInt32 m_nRowStep = 0;
        #endregion
        public Camera()
        {
            InitializeComponent();
        }

        #region 获取相机列表,打开相机,画面显示
        /// <summary>
        /// 打开程序事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            Task task1 = new Task(() =>
                {
                    DeviceListAcq();//枚举设备
                  
                });
            task1.Start();
            task1.Wait();
            OpenCamera();//打开设备
            StartGrab();//连续采图
        }
        /// <summary>
        /// 关闭程序事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            Task.Run(() => 
            {
                CloseCamera();//关闭设备 
            });
            Task.WaitAll();
            Process.GetCurrentProcess().Kill();  
        }
        /// <summary>
        /// 枚举相机
        /// </summary>
        private void DeviceListAcq()
        {
            int nRet;
            // ch:创建设备列表 || en: Create device list
            System.GC.Collect();
            //获取相机的列表,包含网口和U口相机
            nRet = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref m_pDeviceList);
            if (MyCamera.MV_OK != nRet)
            {
                MessageBox.Show("Enum Devices Fail");
                return;
            }
        }
        /// <summary>
        /// 打开设备
        /// </summary>
        private void OpenCamera()
        {
            //判断是否有相机
            if (m_pDeviceList.nDeviceNum == 0)
            {
                MessageBox.Show("No device,please select");
                return;
            }
            //这里选择了第一个相机
            MyCamera.MV_CC_DEVICE_INFO device =
                (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(m_pDeviceList.pDeviceInfo[0],
                                                              typeof(MyCamera.MV_CC_DEVICE_INFO));
            int nRet = -1;
            m_pMyCamera = new MyCamera();
            //获取设备信息
            nRet = m_pMyCamera.MV_CC_CreateDevice_NET(ref device);
            if (MyCamera.MV_OK != nRet)
            {
                return;
            }

            // ch:打开设备 | en:Open device
            nRet = m_pMyCamera.MV_CC_OpenDevice_NET();
            if (MyCamera.MV_OK != nRet)
            {
                MessageBox.Show("Open Device Fail");
                return;
            }

            // ch:获取包大小 || en: Get Payload Size
            MyCamera.MVCC_INTVALUE_EX stParam = new MyCamera.MVCC_INTVALUE_EX();
            nRet = m_pMyCamera.MV_CC_GetIntValueEx_NET("PayloadSize", ref stParam);
            if (MyCamera.MV_OK != nRet)
            {
                MessageBox.Show("Get PayloadSize Fail");
                return;
            }
            g_nPayloadSize = (uint)stParam.nCurValue;

            // ch:获取高 || en: Get Height
            nRet = m_pMyCamera.MV_CC_GetIntValueEx_NET("Height", ref stParam);
            if (MyCamera.MV_OK != nRet)
            {
                MessageBox.Show("Get Height Fail");
                return;
            }
            uint nHeight = (uint)stParam.nCurValue;

            // ch:获取宽 || en: Get Width
            nRet = m_pMyCamera.MV_CC_GetIntValueEx_NET("Width", ref stParam);
            if (MyCamera.MV_OK != nRet)
            {
                MessageBox.Show("Get Width Fail");
                return;
            }
            uint nWidth = (uint)stParam.nCurValue;

            // ch:获取步长 || en: Get nRowStep
            m_nRowStep = nWidth * nHeight;
        }
        /// <summary>
        /// 开始采图
        /// </summary>
        private void StartGrab()
        {
            int nRet;
            // ch:开启抓图 | en:start grab
            nRet = m_pMyCamera.MV_CC_StartGrabbing_NET();
            if (MyCamera.MV_OK != nRet)
            {
                MessageBox.Show("Start Grabbing Fail");
                return;
            }
            m_bGrabbing = true;
            Thread hReceiveImageThreadHandle = new Thread(ReceiveImageWorkThread);
            hReceiveImageThreadHandle.Start(m_pMyCamera);
            //软触发
            m_pMyCamera.MV_CC_SetEnumValue_NET("TriggerSource", 7);
        }
        /// <summary>
        /// 关闭设备
        /// </summary>
        private void CloseCamera()
        {

            if (m_bGrabbing)
            {
                m_bGrabbing = false;
                // ch:停止抓图 || en:Stop grab image
                m_pMyCamera.MV_CC_StopGrabbing_NET();
            }
            // ch:关闭设备 || en: Close device
            m_pMyCamera.MV_CC_CloseDevice_NET();
            m_pMyCamera.MV_CC_DestroyDevice_NET();
            m_bGrabbing = false;
           

        }
        /// <summary>
        /// 显示图片
        /// </summary>
        /// <param name="nHeight">高</param>
        /// <param name="nWidth">宽</param>
        /// <param name="pImageBuf">图片数据</param>
        /// <param name="enPixelType">像素格式</param>
        public void VisionProDisplay(UInt32 nHeight, UInt32 nWidth, IntPtr pImageBuf, MyCamera.MvGvspPixelType enPixelType)
        {
            // ch: 显示 || display
            try
            {
                //黑白图片
                if (enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8)
                {
                    CogImage8Root cogImage8Root = new CogImage8Root();
                    cogImage8Root.Initialize((Int32)nWidth, (Int32)nHeight, pImageBuf, (Int32)nWidth, null);
                    //图像的转换
                    CogImage8Grey cogImage8Grey = new CogImage8Grey();
                    cogImage8Grey.SetRoot(cogImage8Root);
                    //显示图片
                    this.cogRecordDisplay1.Image = cogImage8Grey.ScaleImage((int)nWidth, (int)nHeight);
                    this.cogRecordDisplay1.AutoFit = true;
                    System.GC.Collect();
                }
                else  //彩色图片
                {
                    CogImage8Root image0 = new CogImage8Root();
                    IntPtr ptr0 = new IntPtr(pImageBuf.ToInt64());
                    image0.Initialize((int)nWidth, (int)nHeight, ptr0, (int)nWidth, null);

                    CogImage8Root image1 = new CogImage8Root();
                    IntPtr ptr1 = new IntPtr(pImageBuf.ToInt64() + m_nRowStep);
                    image1.Initialize((int)nWidth, (int)nHeight, ptr1, (int)nWidth, null);

                    CogImage8Root image2 = new CogImage8Root();
                    IntPtr ptr2 = new IntPtr(pImageBuf.ToInt64() + m_nRowStep * 2);
                    image2.Initialize((int)nWidth, (int)nHeight, ptr2, (int)nWidth, null);
                    
                    CogImage24PlanarColor colorImage = new CogImage24PlanarColor();
                    colorImage.SetRoots(image0, image1, image2);

                    this.cogRecordDisplay1.Image = colorImage.ScaleImage((int)nWidth, (int)nHeight);
                    this.cogRecordDisplay1.AutoFit = true;
                    System.GC.Collect();
                }
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.ToString());
                return;
            }
            return;
        }
        /// <summary>
        /// 接收图片线程函数
        /// </summary>
        /// <param name="obj"></param>
        public void ReceiveImageWorkThread(object obj)
        {
            int nRet = MyCamera.MV_OK;
            MyCamera device = obj as MyCamera;
            MyCamera.MV_FRAME_OUT_INFO_EX pFrameInfo = new MyCamera.MV_FRAME_OUT_INFO_EX();
            IntPtr pData = Marshal.AllocHGlobal((int)g_nPayloadSize);
            if (pData == IntPtr.Zero)
            {
                return;
            }
            IntPtr pImageBuffer = Marshal.AllocHGlobal((int)m_nRowStep * 3);
            if (pImageBuffer == IntPtr.Zero)
            {
                return;
            }

            IntPtr pTemp = IntPtr.Zero;
            Byte[] byteArrImageData = new Byte[m_nRowStep * 3];

            while (m_bGrabbing)
            {
                nRet = device.MV_CC_GetOneFrameTimeout_NET(pData, g_nPayloadSize, ref pFrameInfo, 1000);
                if (MyCamera.MV_OK == nRet)
                {
                    MyCamera.MvGvspPixelType pixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed;
                    if (IsColorPixelFormat(pFrameInfo.enPixelType))    // 彩色图像处理
                    {
                        if (pFrameInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed)
                        {
                            pTemp = pData;
                        }
                        else
                        {
                            // 其他格式彩色图像转为RGB
                            nRet = ConvertToRGB(obj, pData, pFrameInfo.nHeight, pFrameInfo.nWidth, pFrameInfo.enPixelType, pImageBuffer);
                            if (MyCamera.MV_OK != nRet)
                            {
                                return;
                            }
                            pTemp = pImageBuffer;
                        }

                        // Packed转Plane
                        unsafe
                        {
                            byte* pBufForSaveImage = (byte*)pTemp;

                            UInt32 nSupWidth = (pFrameInfo.nWidth + (UInt32)3) & 0xfffffffc;

                            for (int nRow = 0; nRow < pFrameInfo.nHeight; nRow++)
                            {
                                for (int col = 0; col < pFrameInfo.nWidth; col++)
                                {
                                    byteArrImageData[nRow * nSupWidth + col] = pBufForSaveImage[nRow * pFrameInfo.nWidth * 3 + (3 * col)];
                                    byteArrImageData[pFrameInfo.nWidth * pFrameInfo.nHeight + nRow * nSupWidth + col] = pBufForSaveImage[nRow * pFrameInfo.nWidth * 3 + (3 * col + 1)];
                                    byteArrImageData[pFrameInfo.nWidth * pFrameInfo.nHeight * 2 + nRow * nSupWidth + col] = pBufForSaveImage[nRow * pFrameInfo.nWidth * 3 + (3 * col + 2)];
                                }
                            }
                            pTemp = Marshal.UnsafeAddrOfPinnedArrayElement(byteArrImageData, 0);
                        }
                    }
                    else if (IsMonoPixelFormat(pFrameInfo.enPixelType))    // Mono图像处理
                    {
                        if (pFrameInfo.enPixelType == MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8)
                        {
                            pTemp = pData;
                        }
                        else
                        {
                            // 其他格式Mono转为Mono8
                            nRet = ConvertToMono8(device, pData, pImageBuffer, pFrameInfo.nHeight, pFrameInfo.nWidth, pFrameInfo.enPixelType);
                            if (MyCamera.MV_OK != nRet)
                            {
                                return;
                            }
                            pTemp = pImageBuffer;
                        }
                        pixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8;
                    }
                    else
                    {
                        continue;
                    }
                    VisionProDisplay(pFrameInfo.nHeight, pFrameInfo.nWidth, pTemp, pixelType);
                }
                else
                {
                    continue;
                }
            }
            if (pData != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(pData);
            }
            if (pImageBuffer != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(pImageBuffer);
            }
            return;
        }
       
        #region  判断图片是黑白还是彩色
        /// <summary>
        /// 图像是否为Mono格式
        /// </summary>
        /// <param name="enType"></param>
        /// <returns></returns>
        private bool IsMonoPixelFormat(MyCamera.MvGvspPixelType enType)
        {
            switch (enType)
            {
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono10:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono10_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono12:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono12_Packed:
                    return true;
                default:
                    return false;
            }
        }

        /// <summary>
        /// 图像是否为彩色
        /// </summary>
        /// <param name="enType"></param>
        /// <returns></returns>
        private bool IsColorPixelFormat(MyCamera.MvGvspPixelType enType)
        {
            switch (enType)
            {
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BGR8_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_RGBA8_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BGRA8_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_YUV422_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_YUV422_YUYV_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR8:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG8:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB8:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG8:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB10:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB10_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG10:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG10_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG10:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG10_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR10:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR10_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB12:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGB12_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG12:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerBG12_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG12:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerRG12_Packed:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR12:
                case MyCamera.MvGvspPixelType.PixelType_Gvsp_BayerGR12_Packed:
                    return true;
                default:
                    return false;
            }
        }

        /// <summary>
        /// 其他黑白格式转为Mono8
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="pInData">输出图片数据</param>
        /// <param name="pOutData">输出图片数据</param>
        /// <param name="nHeight">高</param>
        /// <param name="nWidth">宽</param>
        /// <param name="nPixelType">像素格式</param>
        /// <returns></returns>
        public Int32 ConvertToMono8(object obj, IntPtr pInData, IntPtr pOutData, ushort nHeight, ushort nWidth, MyCamera.MvGvspPixelType nPixelType)
        {
            if (IntPtr.Zero == pInData || IntPtr.Zero == pOutData)
            {
                return MyCamera.MV_E_PARAMETER;
            }

            int nRet = MyCamera.MV_OK;
            MyCamera device = obj as MyCamera;
            MyCamera.MV_PIXEL_CONVERT_PARAM stPixelConvertParam = new MyCamera.MV_PIXEL_CONVERT_PARAM();

            stPixelConvertParam.pSrcData = pInData;//源数据
            if (IntPtr.Zero == stPixelConvertParam.pSrcData)
            {
                return -1;
            }

            stPixelConvertParam.nWidth = nWidth;//图像宽度
            stPixelConvertParam.nHeight = nHeight;//图像高度
            stPixelConvertParam.enSrcPixelType = nPixelType;//源数据的格式
            stPixelConvertParam.nSrcDataLen = (uint)(nWidth * nHeight * ((((uint)nPixelType) >> 16) & 0x00ff) >> 3);

            stPixelConvertParam.nDstBufferSize = (uint)(nWidth * nHeight * ((((uint)MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed) >> 16) & 0x00ff) >> 3);
            stPixelConvertParam.pDstBuffer = pOutData;//转换后的数据
            stPixelConvertParam.enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8;
            stPixelConvertParam.nDstBufferSize = (uint)(nWidth * nHeight * 3);

            nRet = device.MV_CC_ConvertPixelType_NET(ref stPixelConvertParam);//格式转换
            if (MyCamera.MV_OK != nRet)
            {
                return -1;
            }

            return nRet;
        }

        /// <summary>
        /// 其他彩色格式转为RGB8
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="pSrc"></param>
        /// <param name="nHeight"></param>
        /// <param name="nWidth"></param>
        /// <param name="nPixelType"></param>
        /// <param name="pDst"></param>
        /// <returns></returns>
        public Int32 ConvertToRGB(object obj, IntPtr pSrc, ushort nHeight, ushort nWidth, MyCamera.MvGvspPixelType nPixelType, IntPtr pDst)
        {
            if (IntPtr.Zero == pSrc || IntPtr.Zero == pDst)
            {
                return MyCamera.MV_E_PARAMETER;
            }

            int nRet = MyCamera.MV_OK;
            MyCamera device = obj as MyCamera;
            MyCamera.MV_PIXEL_CONVERT_PARAM stPixelConvertParam = new MyCamera.MV_PIXEL_CONVERT_PARAM();

            stPixelConvertParam.pSrcData = pSrc;//源数据
            if (IntPtr.Zero == stPixelConvertParam.pSrcData)
            {
                return -1;
            }

            stPixelConvertParam.nWidth = nWidth;//图像宽度
            stPixelConvertParam.nHeight = nHeight;//图像高度
            stPixelConvertParam.enSrcPixelType = nPixelType;//源数据的格式
            stPixelConvertParam.nSrcDataLen = (uint)(nWidth * nHeight * ((((uint)nPixelType) >> 16) & 0x00ff) >> 3);

            stPixelConvertParam.nDstBufferSize = (uint)(nWidth * nHeight * ((((uint)MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed) >> 16) & 0x00ff) >> 3);
            stPixelConvertParam.pDstBuffer = pDst;//转换后的数据
            stPixelConvertParam.enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_RGB8_Packed;
            stPixelConvertParam.nDstBufferSize = (uint)nWidth * nHeight * 3;

            nRet = device.MV_CC_ConvertPixelType_NET(ref stPixelConvertParam);//格式转换
            if (MyCamera.MV_OK != nRet)
            {
                return -1;
            }

            return MyCamera.MV_OK;
        }
        #endregion
        #endregion

代码整体有点长,主要是解决取流,数据的采集问题,当然大部分的代码都是我按照海康的示例来进行修改的,但也实现了我们需要的功能。

三、网口相机的最好解决方法;

前面讲到,网口相机在VisionPro里面是有现成的工具的,那我们就可以直接引用对应的dll文件使用代码的形式来实现实时画面,而不是必须使用vpp程序的功能来实现画面:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Cognex.VisionPro;
using Cognex.VisionPro.FGGigE;
using Cognex.VisionPro.ToolBlock;

namespace Camera_Live
{
    public partial class Form1 : Form
    {
        ICogAcqFifo mycogCamra;//定义一个相机对象
        private ICogFrameGrabber mFrameGrabber = null;
        List<String> CameraVideo = new List<String>();//相机信息列表


        public Form1()
        {
            InitializeComponent();
        }
        /// <summary>
        /// 获得相机列表,并提示相机数量
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            CogFrameGrabberGigEs GigeCamera = new CogFrameGrabberGigEs();
            if (GigeCamera.Count < 1)
            {
                MessageBox.Show("没有找到相机!");
            }
            for (int i = 0; i < GigeCamera.Count; i++)
            {
                mFrameGrabber = GigeCamera[i];
                //遍历已连接相机信息,相机名称,序列号,模式
                CameraVideo.Add(mFrameGrabber.Name + mFrameGrabber.SerialNumber + mFrameGrabber.AvailableVideoFormats[0]);
            }
            //提示已连接的相机数量
            MessageBox.Show(CameraVideo.Count.ToString());

        }
        /// <summary>
        /// 获取到第一个相机,并显示在控件上
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            //1.获取得相机列表
            CogFrameGrabberGigEs CogCamera = new CogFrameGrabberGigEs();
            //2.取第一个相机,从0开始排序
            ICogFrameGrabber CameraGra = CogCamera[0];
            //3.初始化相机
            mycogCamra = CameraGra.CreateAcqFifo(CameraGra.AvailableVideoFormats[0], CogAcqFifoPixelFormatConstants.Format8Grey, 0, true);
            //4.控件绑定相机并显示画面
            cogRecordDisplay1.StartLiveDisplay(mycogCamra, false);
            //5.相机的几个重要参数显示
            MessageBox.Show("相机曝光:" + mycogCamra.OwnedExposureParams.Exposure.ToString() + "增益:" +
                mycogCamra.OwnedBrightnessParams.Brightness.ToString() + "伽马" + mycogCamra.OwnedContrastParams.Contrast.ToString());


        }
    }
}

这种方法只适合与网口相机,还是比较实用的;

  • 13
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值