Basler相机Sdk采图的演示例程(C#)

机器ppm不达标的情况下,往往对视觉的处理速度有变态的要求,为了争取处理时间最短,几十毫秒也要争取。

halcon的接口是通用接口,其速度是比不上相机厂商自己相机配套的SDK的采图速度的。

下面程序运行后,500w的CCD拍图的时间(不算显示时间)达到惊人的32毫秒,如果用halcon接口,最快的我见过是180毫秒。

image.png

using Basler.Pylon;
using HalconDotNet;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private PixelDataConverter converter = new PixelDataConverter();
          /// <summary>
        /// 相机ID
        /// </summary>
        public string UserID { get { return userID; } }
        private string userID = string.Empty;

        private Stopwatch sw = new Stopwatch();
        private bool isOkGrab = false;
        private IntPtr latestFrameAddress = IntPtr.Zero;
        public HObject Image { get { return image; } }
        private HObject image = null;
        static Version Sfnc2_0_0 = new Version(2, 0, 0);
        private Camera camera = null;
        HTuple handle;
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            var f1=BaslerCameraInit();
            if(f1)
            {
               MessageBox.Show( Open().ToString());
            }
        }

        
        /// <summary>
        /// 实例化第一个找到的相机
        /// </summary>
        public bool BaslerCameraInit()
        {
            try
            {
                camera = new Camera();
                  camera.StreamGrabber.ImageGrabbed -= StreamGrabber_ImageGrabbed;
                camera.StreamGrabber.ImageGrabbed+=StreamGrabber_ImageGrabbed;
                return true;
            }
            catch (Exception ex)
            {
                return false;
              //NotifyG.Error(ex.ToString());
            }
        }


         /// <summary>
        /// 根据相机UserID实例化相机
        /// </summary>
        /// <param name="UserID"></param>
        public bool BaslerCameraInit(string userID)
        {
            try
            {
                // 枚举相机列表
                List<ICameraInfo> allCameraInfos = CameraFinder.Enumerate();
                foreach (ICameraInfo cameraInfo in allCameraInfos)
                {
                    if (userID == cameraInfo[CameraInfoKey.UserDefinedName])
                    {
                        this.userID = userID;
                        camera = new Camera(cameraInfo);
                        camera.StreamGrabber.ImageGrabbed -= StreamGrabber_ImageGrabbed;
                        camera.StreamGrabber.ImageGrabbed += StreamGrabber_ImageGrabbed;
                    }
                }
                if (camera == null)
                {
                    //NotifyG.Error("未识别到UserID为“" + UserID + "”的相机!");
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {
                return false;
                //NotifyG.Error(ex.ToString());
            }
        }


        void StreamGrabber_ImageGrabbed(object sender, ImageGrabbedEventArgs e)
        {
            try
            {
                // Acquire the image from the camera. Only show the latest image. The camera may acquire images faster than the images can be displayed.

                // Get the grab result.
                IGrabResult grabResult = e.GrabResult;

                // Check if the image can be displayed.
                if (grabResult.IsValid)
                {
                    //grabTime = sw.ElapsedMilliseconds;
                    //if (eventComputeGrabTime != null) eventComputeGrabTime(grabTime);

                    //Reduce the number of displayed images to a reasonable amount if the camera is acquiring images very fast.
                    // ****  降低显示帧率,减少CPU占用率  **** //
                    //if (!stopWatch.IsRunning || stopWatch.ElapsedMilliseconds > 33)
                    {
                        //stopWatch.Restart();
                        // 判断是否是黑白图片格式
                        if (grabResult.PixelTypeValue == PixelType.Mono8)
                        {
                            //allocate the m_stream_size amount of bytes in non-managed environment 
                            if (latestFrameAddress == IntPtr.Zero)
                            {
                                latestFrameAddress = Marshal.AllocHGlobal((Int32)grabResult.PayloadSize);
                            }
                            converter.OutputPixelFormat = PixelType.Mono8;
                            converter.Convert(latestFrameAddress, grabResult.PayloadSize, grabResult);
                            HOperatorSet.GenEmptyObj(out image);
                            image.Dispose();
                            // 转换为Halcon图像显示
                            HOperatorSet.GenImage1(out image, "byte", grabResult.Width, grabResult.Height, latestFrameAddress);
                            HOperatorSet.SetPart(handle, 0, 0, grabResult.Height - 1, grabResult.Width - 1);
                        }
                        else if (grabResult.PixelTypeValue == PixelType.BayerBG8 || grabResult.PixelTypeValue == PixelType.BayerGB8
                                    || grabResult.PixelTypeValue == PixelType.BayerRG8 || grabResult.PixelTypeValue == PixelType.YUV422packed)
                        {
                            int imageWidth = grabResult.Width - 1;
                            int imageHeight = grabResult.Height - 1;
                            HOperatorSet.SetPart(handle, 0, 0, imageHeight, imageWidth);
                            int payloadSize = imageWidth * imageHeight;

                            //allocate the m_stream_size amount of bytes in non-managed environment 
                            if (latestFrameAddress == IntPtr.Zero)
                            {
                                latestFrameAddress = Marshal.AllocHGlobal((Int32)(3 * payloadSize));
                            }
                            converter.OutputPixelFormat = PixelType.RGB8packed;     // 根据下面halcon转换的色彩格式bgr
                            converter.Parameters[PLPixelDataConverter.InconvertibleEdgeHandling].SetValue("Clip");
                            converter.Convert(latestFrameAddress, 3 * payloadSize, grabResult);

                            HOperatorSet.GenImageInterleaved(out image, latestFrameAddress, "bgr",
                                     (HTuple)imageWidth, (HTuple)imageHeight, -1, "byte", (HTuple)imageWidth, (HTuple)imageHeight, 0, 0, -1, 0);
                        }
                        else
                        {
                            //NotifyG.Error(DeviceName + "拍照失败,相机图像格式设置");
                            return;
                        }
                        isOkGrab = true;
                        //MessageBox.Show(isOkGrab.ToString());
                        // 抛出图像处理事件
                        //if (EventGrab != null) EventGrab(this, new CameraGrabEventArgs(image));
                    }
                }
            
            }
            catch (Exception ex)
            {
                //MessageBox.Show(ex.ToString());
                return;
            }
            finally
            {
                // Dispose the grab result if needed for returning it to the grab loop.
                e.DisposeGrabResultIfClone();
            }
        }

        /// <summary>
        /// 打开相机
        /// </summary>
        public bool Open()
        {
            try
            {
                if (camera.IsOpen) camera.Close();
                Thread.Sleep(200);
                camera.Open();
                var imageWidth = camera.Parameters[PLCamera.Width].GetValue();               // 获取图像宽 
                var imageHeight = camera.Parameters[PLCamera.Height].GetValue();              // 获取图像高
                GetMinMaxExposureTime();
                GetMinMaxGain();
                camera.Parameters[PLCamera.AcquisitionMode].SetValue(PLCamera.AcquisitionMode.SingleFrame);
                //NotifyG.Debug(DeviceName + "打开相机成功:" + userID);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                return false;
            }
            return true;
        }

        /// <summary>
        /// 关闭相机,释放相关资源
        /// </summary>
        public new bool Close()
        {
            try
            {
                camera.Close();
                camera.Dispose();
                if (Image != null)
                {
                    Image.Dispose();
                }
                if (latestFrameAddress != null)
                {
                    Marshal.FreeHGlobal(latestFrameAddress);
                    latestFrameAddress = IntPtr.Zero;
                }
                //NotifyG.Debug(DeviceName + "关闭相机成功:" + userID);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                return false;
            }
            return true;
        }

        /// <summary>
        /// 单张采集
        /// </summary>
        public bool GrabImage()
        {
            try
            {
                isOkGrab = false;
                sw.Restart();
                if (camera.StreamGrabber.IsGrabbing)
                {
                    //NotifyG.Error("相机当前正处于采集状态!");
                    return false;
                }
                else
                {
                    camera.StreamGrabber.Start(1, GrabStrategy.LatestImages, GrabLoop.ProvidedByStreamGrabber);
                    //while (!isOkGrab)
                    //{
                    //    if (sw.ElapsedMilliseconds > 2000) { isOkGrab = false; return false; }
                    //    Thread.Sleep(1);
                    //}
                    //NotifyG.Debug(DeviceName + "拍照成功:" + sw.ElapsedMilliseconds);
                    return true;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                return false;
            }
            return true;
        }

        /// <summary>
        /// 开始连续采集
        /// </summary>
        public bool StartGrabbing()
        {
            try
            {
                if (camera.StreamGrabber.IsGrabbing)
                {
                    //NotifyG.Error("相机当前正处于采集状态!");
                    return false;
                }
                else
                {
                    camera.Parameters[PLCamera.AcquisitionMode].SetValue(PLCamera.AcquisitionMode.Continuous);
                    camera.StreamGrabber.Start(GrabStrategy.LatestImages, GrabLoop.ProvidedByStreamGrabber);
                 
                    return true;
                }
            }
            catch (Exception ex)
            {
                //NotifyG.Error(DeviceName + ex.ToString());
                return false;
            }
        }

        /// <summary>
        /// 停止连续采集
        /// </summary>
        public bool StopGrabbing()
        {
            try
            {
                if (camera.StreamGrabber.IsGrabbing)
                {
                    camera.StreamGrabber.Stop();
                }
            }
            catch (Exception ex)
            {
                //NotifyG.Error(DeviceName + ex.ToString());
            }
            return true;
        }


        /// <summary>
        /// 获取最小最大曝光时间
        /// </summary>
        public void GetMinMaxExposureTime()
        {
            try
            {
                if (camera.GetSfncVersion() < Sfnc2_0_0)
                {
                    var minExposureTime = camera.Parameters[PLCamera.ExposureTimeRaw].GetMinimum();
                    var maxExposureTime = camera.Parameters[PLCamera.ExposureTimeRaw].GetMaximum();
                }
                else
                {
                    var minExposureTime = (long)camera.Parameters[PLUsbCamera.ExposureTime].GetMinimum();
                    var maxExposureTime = (long)camera.Parameters[PLUsbCamera.ExposureTime].GetMaximum();
                }
            }
            catch (Exception ex)
            {
                
            }
        }

        /// <summary>
        /// 获取最小最大增益
        /// </summary>
        public void GetMinMaxGain()
        {
            try
            {
                if (camera.GetSfncVersion() < Sfnc2_0_0)
                {
                    var minGain = camera.Parameters[PLCamera.GainRaw].GetMinimum();
                    var maxGain = camera.Parameters[PLCamera.GainRaw].GetMaximum();
                }
                else
                {
                    var minGain = (long)camera.Parameters[PLUsbCamera.Gain].GetMinimum();
                    var maxGain = (long)camera.Parameters[PLUsbCamera.Gain].GetMaximum();
                }
            }
            catch (Exception ex)
            {
                //NotifyG.Error(DeviceName + ex.ToString());
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Stopwatch sw1 = new Stopwatch();
            sw1.Start();
            var f1 = GrabImage();
            sw1.Stop();
            MessageBox.Show(string.Format("grab time:{0}",sw1.ElapsedMilliseconds));
            //if(f1)
            //{
            //    if (null != Image)
            //        HOperatorSet.DispObj(Image, hWindowControl1.Handle);
            //}
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (null != camera && camera.IsOpen)
                Close();
        }

        private void button6_Click(object sender, EventArgs e)
        {
            try
            {
                if (null != Image && Image.IsInitialized())
                {
                    //HOperatorSet.WriteImage(Image, "bmp", 0, "d:\\123.bmp");
                    HOperatorSet.DispObj(Image, handle);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            handle = hWindowControl1.HalconWindow;
           
        }

        private void button3_Click(object sender, EventArgs e)
        {
            timer1.Start();
            StartGrabbing();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            timer1.Stop();
            StopGrabbing();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            button6_Click(null, null);
        }


    }
}

 

当这个程序被强行在进程中关闭后,你会发现再启动程序就初始化相机失败。

这是因为相机的句柄没有被关闭。上面的演示例程中,关闭句柄被放在了form窗口正常关闭的时候。

你重启电脑可以解决这个问题,或者你也可以等个几分钟,再启动程序也可以连上相机。

下面附上常见工业相机的SDK开发资料网址:

Basler相机

Basler pylon相机软件套装是一款包含易于使用的SDK、驱动程序和工具的软件套装,您可通过Windows、Linux PC或Mac来操作任何一款Basler相机。pylon采用最新GenICam技术,可无限制访问最新型号的相机并使用相关功能。

Basler – 德国工业相机_工业镜头_工业光源_线材等视觉组件提供商

机器视觉软件及工业相机软件下载 - pylon, ToF 等 | Basler

MvCameraControl海康相机

海康机器人Hikrobot-官方网站

海康机器人Hikrobot-官方网站

机器视觉工业相机客户端MVS V3.1.0

软件版本:MVS3.1.0 build20181229

TIS映美精工业相机,映美精IC Imageing Control.net

Machine vision software and drivers for Microsoft Windows

https://www.theimagingsource.com/support/downloads-for-windows/software-development-kits-sdks/icimagingcontrol/

Software Development Kits (SDKs)

IC Imaging Control .NET Component for C#, VB.NET, C++ Class Library for C++ projects

ic_setup_3.4.0.2744.exe

Teledyne DALSA

Sapera LT SDK是一款图像采集与控制软件的开发工具包(SDK),用于Teledyne DALSA相机与采集卡。Sapera LT支持从相机与采集卡中采集图像,依据的标准包括GigE Vision;CameraLink与CameraLink HS。GigE Vision是一种基于千兆以太网通信协议开发的相机接口标准。

Sapera LT | Teledyne DALSA

www.lustervision.com/dalsa-linea/

Sapera LT SDK - 软件 - 志强视觉科技

大恒相机

大恒图像-专业的机器视觉核心部件及解决方案供应商

Point Grey相机

FlyCapture SDK是加拿大Point Grey(灰点)公司开发的功能丰富,最稳定的软件套件。

FlyCapture SDK | Teledyne FLIR

Machine Vision – Area Scan Cameras | Teledyne FLIR

  • 0
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

~晓广~

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

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

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

打赏作者

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

抵扣说明:

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

余额充值