一、通过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: