C# 联合 VisionPro 进行相机采集

一、前置条件

  1. 硬件 / 软件准备
    • 工业相机(支持 GenICam/ GigE/ USB3 Vision 协议,如 Basler、Hikvision、Keyence 等)
    • 已安装相机厂商驱动和 VisionPro 相机适配包(Cognex FrameGrabber)
    • 确保 VisionPro 的Cognex.VisionPro.FrameGrabber.dll已添加到项目引用
  2. 核心概念
    • 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("资源已全部释放!");
        }
    }
}

三、关键代码解释

  1. 相机枚举与连接

    • CogFrameGrabber.Show(true):弹出相机选择窗口,让用户选择要连接的相机(也可通过CogFrameGrabber.FrameGrabbers静默枚举)。
    • CreateAcqFifo:创建采集队列,参数说明:
      • "Default":相机配置文件名称(可在 VisionPro 中预设);
      • CogAcqFifoPixelFormatConstants.Mono8:像素格式(8 位灰度,工业场景首选);
      • 1:队列长度(单次采图设 1 即可);
      • false:非共享模式。
  2. 单次采图核心

    • _acqFifo.Acquire(5000, out bool timedOut):阻塞式采图,第一个参数是超时时间(ms),超时后timedOuttrue
    • CogImage8Grey(imageData):将原始采集数据转换为 VisionPro 可处理的灰度图像对象。
  3. 连续采图核心

    • 必须使用后台线程Thread)执行连续采图,避免阻塞 UI 线程导致界面卡死。
    • 每次采图后需调用image.Dispose()释放图像资源,否则会导致内存持续上涨。
  4. 图像显示

    • CogDisplay是 VisionPro 官方的图像显示控件,支持缩放、标注、ROI 显示等功能。
    • 跨线程更新 UI 需使用Invoke方法,否则会抛出跨线程访问异常。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

工业程序猿老赵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值