一、前置条件
- 硬件 / 软件准备:
- 工业相机(支持 GenICam/ GigE/ USB3 Vision 协议,如 Basler、Hikvision、Keyence 等)
- 已安装相机厂商驱动和 VisionPro 相机适配包(Cognex FrameGrabber)
- 确保 VisionPro 的
Cognex.VisionPro.FrameGrabber.dll已添加到项目引用
- 核心概念:
CogFrameGrabber:VisionPro 中管理相机的核心类,用于枚举、连接相机CogAcqFifo:采集队列,用于控制相机的单次 / 连续采图CogImageData:采集到的图像数据对象
二、完整相机采集代码示例
以下示例包含枚举相机、连接相机、单次采图、连续采图、释放资源等核心功能,可直接运行:
using System;
using System.Linq;
using Cognex.VisionPro;
using Cognex.VisionPro.FrameGrabber;
using Cognex.VisionPro.Display;
using System.Threading;
namespace VisionProCameraCapture
{
class CameraCaptureDemo
{
// 相机核心对象
private CogFrameGrabber _frameGrabber; // 帧采集器(相机)
private CogAcqFifo _acqFifo; // 采集队列
private CogDisplay _cogDisplay; // 图像显示控件(WinForm用)
private bool _isContinuousCapture = false; // 是否连续采集
private Thread _captureThread; // 连续采集线程
// WinForm窗体(示例用,可替换为你的窗体)
private System.Windows.Forms.Form _mainForm;
static void Main(string[] args)
{
CameraCaptureDemo demo = new CameraCaptureDemo();
try
{
// 1. 初始化窗体和显示控件(可选,用于可视化)
demo.InitDisplayForm();
// 2. 枚举并连接相机
if (!demo.ConnectCamera())
{
Console.WriteLine("相机连接失败!");
return;
}
// 示例1:单次采图
Console.WriteLine("开始单次采图...");
var singleImage = demo.CaptureSingleImage();
if (singleImage != null)
{
Console.WriteLine("单次采图成功!");
demo.ShowImage(singleImage); // 显示图像
}
// 示例2:连续采图(运行5秒后停止)
Console.WriteLine("开始连续采图(5秒后停止)...");
demo.StartContinuousCapture();
Thread.Sleep(5000); // 采集5秒
demo.StopContinuousCapture();
Console.WriteLine("连续采图已停止!");
}
catch (Exception ex)
{
Console.WriteLine($"程序异常:{ex.Message}");
Console.WriteLine($"异常详情:{ex.StackTrace}");
}
finally
{
// 3. 释放所有资源
demo.DisposeAllResources();
}
Console.WriteLine("按任意键退出...");
Console.ReadLine();
}
/// <summary>
/// 初始化显示窗体和CogDisplay控件(WinForm)
/// </summary>
private void InitDisplayForm()
{
_mainForm = new System.Windows.Forms.Form();
_mainForm.Text = "VisionPro相机采集预览";
_mainForm.Size = new System.Drawing.Size(800, 600);
// 创建VisionPro图像显示控件
_cogDisplay = new CogDisplay();
_cogDisplay.Dock = System.Windows.Forms.DockStyle.Fill;
_mainForm.Controls.Add(_cogDisplay);
// 显示窗体
_mainForm.Show();
}
/// <summary>
/// 枚举相机并建立连接
/// </summary>
/// <returns>是否连接成功</returns>
public bool ConnectCamera()
{
try
{
// 1. 获取所有可用的帧采集器(相机)
CogFrameGrabber[] frameGrabbers = CogFrameGrabber.Show(true);
if (frameGrabbers == null || frameGrabbers.Length == 0)
{
Console.WriteLine("未检测到任何相机!");
return false;
}
// 2. 选择第一个相机(也可根据相机名称/ID筛选)
_frameGrabber = frameGrabbers[0];
Console.WriteLine($"已找到相机:{_frameGrabber.Name}");
// 3. 创建采集队列(AcqFifo)
// VideoFormat:相机分辨率/像素格式(可通过相机配置工具预设)
_acqFifo = _frameGrabber.CreateAcqFifo("Default", CogAcqFifoPixelFormatConstants.Mono8, 1, false);
_acqFifo.Start(); // 启动采集队列
Console.WriteLine("相机连接成功!");
return true;
}
catch (Exception ex)
{
Console.WriteLine($"相机连接异常:{ex.Message}");
return false;
}
}
/// <summary>
/// 单次采图
/// </summary>
/// <returns>采集到的图像对象</returns>
public CogImage8Grey CaptureSingleImage()
{
if (_acqFifo == null || !_acqFifo.Running)
{
Console.WriteLine("采集队列为空或未启动!");
return null;
}
try
{
// 等待采集图像(超时时间5000ms)
CogImageData imageData = _acqFifo.Acquire(5000, out bool timedOut);
if (timedOut)
{
Console.WriteLine("单次采图超时!");
return null;
}
// 转换为8位灰度图(工业视觉常用)
CogImage8Grey greyImage = new CogImage8Grey(imageData);
imageData.Dispose(); // 释放原始图像数据
return greyImage;
}
catch (Exception ex)
{
Console.WriteLine($"单次采图失败:{ex.Message}");
return null;
}
}
/// <summary>
/// 开始连续采图
/// </summary>
public void StartContinuousCapture()
{
if (_isContinuousCapture || _acqFifo == null)
return;
_isContinuousCapture = true;
// 启动后台线程采集(避免阻塞UI)
_captureThread = new Thread(ContinuousCaptureLoop)
{
IsBackground = true // 后台线程,程序退出时自动终止
};
_captureThread.Start();
}
/// <summary>
/// 连续采图循环
/// </summary>
private void ContinuousCaptureLoop()
{
while (_isContinuousCapture)
{
var image = CaptureSingleImage();
if (image != null)
{
ShowImage(image); // 实时显示图像
image.Dispose(); // 释放图像资源(避免内存暴涨)
}
Thread.Sleep(10); // 控制采集频率(可根据需求调整)
}
}
/// <summary>
/// 停止连续采图
/// </summary>
public void StopContinuousCapture()
{
_isContinuousCapture = false;
// 等待线程结束
if (_captureThread != null && _captureThread.IsAlive)
{
_captureThread.Join(1000);
}
}
/// <summary>
/// 在CogDisplay控件中显示图像
/// </summary>
/// <param name="image">要显示的图像</param>
public void ShowImage(CogImage8Grey image)
{
if (_cogDisplay == null || image == null)
return;
// 跨线程访问UI控件需用Invoke
_cogDisplay.Invoke(new Action(() =>
{
_cogDisplay.Image = image;
_cogDisplay.Fit(true); // 自适应显示
}));
}
/// <summary>
/// 释放所有资源(关键!)
/// </summary>
public void DisposeAllResources()
{
// 停止连续采集
StopContinuousCapture();
// 释放采集队列
if (_acqFifo != null)
{
if (_acqFifo.Running)
_acqFifo.Stop();
_acqFifo.Dispose();
_acqFifo = null;
}
// 释放帧采集器
if (_frameGrabber != null)
{
_frameGrabber.Dispose();
_frameGrabber = null;
}
// 释放显示控件和窗体
if (_cogDisplay != null)
{
_cogDisplay.Dispose();
_cogDisplay = null;
}
if (_mainForm != null)
{
_mainForm.Close();
_mainForm.Dispose();
}
// 强制垃圾回收
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("资源已全部释放!");
}
}
}
三、关键代码解释
-
相机枚举与连接:
CogFrameGrabber.Show(true):弹出相机选择窗口,让用户选择要连接的相机(也可通过CogFrameGrabber.FrameGrabbers静默枚举)。CreateAcqFifo:创建采集队列,参数说明:"Default":相机配置文件名称(可在 VisionPro 中预设);CogAcqFifoPixelFormatConstants.Mono8:像素格式(8 位灰度,工业场景首选);1:队列长度(单次采图设 1 即可);false:非共享模式。
-
单次采图核心:
_acqFifo.Acquire(5000, out bool timedOut):阻塞式采图,第一个参数是超时时间(ms),超时后timedOut为true。CogImage8Grey(imageData):将原始采集数据转换为 VisionPro 可处理的灰度图像对象。
-
连续采图核心:
- 必须使用后台线程(
Thread)执行连续采图,避免阻塞 UI 线程导致界面卡死。 - 每次采图后需调用
image.Dispose()释放图像资源,否则会导致内存持续上涨。
- 必须使用后台线程(
-
图像显示:
CogDisplay是 VisionPro 官方的图像显示控件,支持缩放、标注、ROI 显示等功能。- 跨线程更新 UI 需使用
Invoke方法,否则会抛出跨线程访问异常。
4302

被折叠的 条评论
为什么被折叠?



