【basler】Chapter5:basler相机C#代码实现与详解

1、简介

最近使用basler相机,摸索了一段时间,找过一些其他的代码,有的不管用,有的只能拍照,无法处理相片流。其中有一个博客代码简洁明了,可以做入门学习,但是只能拍照不能录像:
https://blog.csdn.net/gy0124/article/details/103469354

以下将介绍可以实现拍照、录像功能的代码。
建议先看上面的博客,对代码有大致框架了解后再看下面的代码。

2、basler C# demo

2.1 使用到的控件
功能和控件控件名称
拍照 buttontoolStripButtonOneShot
录像 buttontoolStripButtonContinuousShot
停止 buttontoolStripButtonStop
相机列表 listviewUpdateDeviceList
定时器 timerupdateDeviceListTimer
窗体formMainForm
2.2 代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using PylonLiveView;
using Basler.Pylon; //引入basler的动态链接库

namespace PylonLiveView
{
    // 主界面
    public partial class MainForm : Form
    {
        private Camera camera = null;//实例化一个camera
        private PixelDataConverter converter = new PixelDataConverter();//后面处理图像数据
        private Stopwatch stopWatch = new Stopwatch();//用于准确测量运行时间

        // 构造函数
        public MainForm()
        {
            InitializeComponent();

            /* 设置参数名称。如果不需要可以删掉
            testImageControl.DefaultName = "Test Image Selector";
            pixelFormatControl.DefaultName = "Pixel Format";
            widthSliderControl.DefaultName = "Width";
            heightSliderControl.DefaultName = "Height";
            gainSliderControl.DefaultName = "Gain";
            exposureTimeSliderControl.DefaultName = "Exposure Time";*/

            //更新相机列表:定时器定时刷新列表,将找到的相机名称显示在列表上
            UpdateDeviceList();

            //按钮使能状态:两个按钮(拍照和录像)
            EnableButtons(false, false);
        }


        // 拍照的按钮(点击事件)
        private void toolStripButtonOneShot_Click(object sender, EventArgs e)
        {
            OneShot(); // Start the grabbing of one image.
        }


        //录像的按钮(点击事件)
        private void toolStripButtonContinuousShot_Click(object sender, EventArgs e)
        {
            ContinuousShot(); // Start the grabbing of images until grabbing is stopped.
        }


        // 停止按钮(点击事件)
        private void toolStripButtonStop_Click(object sender, EventArgs e)
        {
            Stop(); // 停止抓取图像
        }


        //事件(连接断开)
        private void OnConnectionLost(Object sender, EventArgs e)
        {
            if (InvokeRequired)
            {
                // 如果未触发,新建立一个事件
                BeginInvoke(new EventHandler<EventArgs>(OnConnectionLost), sender, e);
                return;
            }
            //断开相机
            DestroyCamera();
            //更新相机列表
            UpdateDeviceList();
        }


        // 事件(打开相机)
        private void OnCameraOpened(Object sender, EventArgs e)
        {
            if (InvokeRequired)
            {
                BeginInvoke(new EventHandler<EventArgs>(OnCameraOpened), sender, e);
                return;
            }

            // 使能按钮(如果打开了,拍照和录像按钮显示可用)
            EnableButtons(true, false);
        }


        // 事件(关闭相机)
        private void OnCameraClosed(Object sender, EventArgs e)
        {
            if (InvokeRequired)
            {
                BeginInvoke(new EventHandler<EventArgs>(OnCameraClosed), sender, e);
                return;
            }

            // 不使能按钮(如果断开了,拍照和录像按钮显示不可用)
            EnableButtons(false, false);
        }


        // 事件(抓取相片)
        private void OnGrabStarted(Object sender, EventArgs e)
        {
            if (InvokeRequired)
            {
                BeginInvoke(new EventHandler<EventArgs>(OnGrabStarted), sender, e);
                return;
            }

            //停止时测量,并将事件设置为0
            stopWatch.Reset();

            //停止更新列表
            updateDeviceListTimer.Stop();

            //不使能按钮(如果断开了,拍照和录像按钮显示不可用)
            EnableButtons(false, true);
        }


        // 事件(抓取相片后的图像处理)
        private void OnImageGrabbed(Object sender, ImageGrabbedEventArgs e)
        {
            if (InvokeRequired)
            {
                BeginInvoke(new EventHandler<ImageGrabbedEventArgs>(OnImageGrabbed), sender, e.Clone());
                return;
            }

            try
            {
                // 获取相片
                IGrabResult grabResult = e.GrabResult;

                //如获取相片为true
                if (grabResult.IsValid)
                {
                    if (!stopWatch.IsRunning || stopWatch.ElapsedMilliseconds > 33)
                    {
                        stopWatch.Restart();
                        //把抓取到的图片放在bitmap
                        Bitmap bitmap = new Bitmap(grabResult.Width, grabResult.Height, PixelFormat.Format32bppRgb);
                        // 一下是图像格式转换(如果需要换成HImage或者其他格式,修改此处代码)
                        BitmapData bmpData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
                        converter.OutputPixelFormat = PixelType.BGRA8packed;
                        IntPtr ptrBmp = bmpData.Scan0;
                        converter.Convert(ptrBmp, bmpData.Stride * bitmap.Height, grabResult);
                        bitmap.UnlockBits(bmpData);

                        // 临时bitmap用于释放上一个bitmap
                        Bitmap bitmapOld = pictureBox.Image as Bitmap;
                        
                        //把抓取图像放在picturebox显示
                        pictureBox.Image = bitmap;
                        //如果想要保存图片,savepath是保存路径,比如public string savePath = "D:/download/0.jpg";
                        //bitmap.Save(savePath, System.Drawing.Imaging.ImageFormat.Jpeg);
                        
                        if (bitmapOld != null)
                        {
                            // 释放bitmap
                            bitmapOld.Dispose();
                        }
                    }
                }
            }
            catch (Exception exception)
            {
                ShowException(exception);
            }
            finally
            {
                // 释放
                e.DisposeGrabResultIfClone();
            }
        }


        // 事件(停止抓取)
        private void OnGrabStopped(Object sender, GrabStopEventArgs e)
        {
            if (InvokeRequired)
            {
                BeginInvoke(new EventHandler<GrabStopEventArgs>(OnGrabStopped), sender, e);
                return;
            }
            stopWatch.Reset();

            //开始更新列表
            updateDeviceListTimer.Start();
            //跟上面相同,不赘述
            EnableButtons(true, false);

            if(e.Reason != GrabStopReason.UserRequest)
            {
                MessageBox.Show("A grab error occured:\n" + e.ErrorMessage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        // 相机使能方法
        private void EnableButtons(bool canGrab, bool canStop)
        {
            toolStripButtonContinuousShot.Enabled = canGrab;
            toolStripButtonOneShot.Enabled = canGrab;
            toolStripButtonStop.Enabled = canStop;
        }

        // 关闭相机
        private void Stop()
        {
            try
            {
                camera.StreamGrabber.Stop();
            }
            catch (Exception exception)
            {
                ShowException(exception);
            }
        }

        // 断开相机
        private void DestroyCamera()
        {
            /* 清空相机参数
            try
            {
                if (camera != null)
                {

                    testImageControl.Parameter = null;
                    pixelFormatControl.Parameter = null;
                    widthSliderControl.Parameter = null;
                    heightSliderControl.Parameter = null;
                    gainSliderControl.Parameter = null;
                    exposureTimeSliderControl.Parameter = null;
                }
            }
            catch (Exception exception)
            {
                ShowException(exception);
            }*/

            // 断开相机
            try
            {
                if (camera != null)
                {
                    camera.Close();
                    camera.Dispose();
                    camera = null;
                }
            }
            catch (Exception exception)
            {
                ShowException(exception);
            }

            // 释放转换
            if (converter != null)
            {
                converter.Dispose();
                converter = null;
            }
        }

        // 拍照方法
        private void OneShot()
        {
            try
            {
                camera.Parameters[PLCamera.AcquisitionMode].SetValue(PLCamera.AcquisitionMode.SingleFrame);
                camera.StreamGrabber.Start(1, GrabStrategy.OneByOne, GrabLoop.ProvidedByStreamGrabber);
            }
            catch (Exception exception)
            {
                ShowException(exception);
            }
        }

        // 录像方法
        private void ContinuousShot()
        {
            try
            {
               camera.Parameters[PLCamera.AcquisitionMode].SetValue(PLCamera.AcquisitionMode.Continuous);
                camera.StreamGrabber.Start(GrabStrategy.OneByOne, GrabLoop.ProvidedByStreamGrabber);
            }
            catch (Exception exception)
            {
                ShowException(exception);
            }
        }

        // 更新列表方法
        private void UpdateDeviceList()
        {
            try
            {
                // 查询相机
                List<ICameraInfo> allCameras = CameraFinder.Enumerate();

                ListView.ListViewItemCollection items = deviceListView.Items;

                // 遍历找到的相机
                foreach (ICameraInfo cameraInfo in allCameras)
                {
                    // 设置找到新相机的bool参数
                    bool newitem = true;
                    foreach (ListViewItem item in items)
                    {
                        ICameraInfo tag = item.Tag as ICameraInfo;

                        // 如果列表的item名称跟相机名称一致,说明不是新的相机
                        if ( tag[CameraInfoKey.FullName] == cameraInfo[CameraInfoKey.FullName])
                        {
                            tag = cameraInfo;
                            newitem = false;
                            break;
                        }
                    }

                    // 如果有新的相机,把相机加到listview
                    if (newitem)
                    {
                        ListViewItem item = new ListViewItem(cameraInfo[CameraInfoKey.FriendlyName]);
                        string toolTipText = "";
                        foreach( KeyValuePair<string, string> kvp in cameraInfo)
                        {
                            toolTipText += kvp.Key + ": " + kvp.Value + "\n";
                        }
                        item.ToolTipText = toolTipText;
                        item.Tag = cameraInfo;
                        deviceListView.Items.Add(item);
                    }
                }

                //移除断开的相机
                foreach (ListViewItem item in items)
                {
                    bool exists = false;

                    // 如果listview的item没有一个跟找到的相机匹配,则移除
                    foreach (ICameraInfo cameraInfo in allCameras)
                    {
                        if (((ICameraInfo)item.Tag)[CameraInfoKey.FullName] == cameraInfo[CameraInfoKey.FullName])
                        {
                            exists = true;
                            break;
                        }
                    }
                    if (!exists)
                    {
                        deviceListView.Items.Remove(item);
                    }
                }
            }
            catch (Exception exception)
            {
                ShowException(exception);
            }
        }
        
        private void ShowException(Exception exception)
        {
            MessageBox.Show("Exception caught:\n" + exception.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        // 关闭窗体时,断开相机
        private void MainForm_FormClosing(object sender, FormClosingEventArgs ev)
        {
            // Close the camera object.
            DestroyCamera();
        }

        //当选择新相机时,断开已有相机,连接新相机
        private void deviceListView_SelectedIndexChanged(object sender, EventArgs ev)
        {
            if (camera != null)
            {
                DestroyCamera();
            }

            if (deviceListView.SelectedItems.Count > 0)
            {
                ListViewItem item = deviceListView.SelectedItems[0];
                ICameraInfo selectedCamera = item.Tag as ICameraInfo;
                try
                {
                    camera = new Camera (selectedCamera);
                    camera.CameraOpened += Configuration.AcquireContinuous;
                    camera.Open();
                    // 相机事件与订阅者设置(详情看委托与事件,这里streamGrabber里有三个事件,分别关联三个方法,这三个方法在前面的代码。这是区别与其他博客代码的地方,也是实现相机不断抓取相片流的地方。)
                    camera.ConnectionLost += OnConnectionLost;
                    camera.CameraOpened += OnCameraOpened;
                    camera.CameraClosed += OnCameraClosed;
                    camera.StreamGrabber.GrabStarted += OnGrabStarted;
                    camera.StreamGrabber.ImageGrabbed += OnImageGrabbed;
                    camera.StreamGrabber.GrabStopped += OnGrabStopped;

                    /*Set the parameter for the controls.
                    testImageControl.Parameter = camera.Parameters[PLCamera.TestImageSelector];
                    pixelFormatControl.Parameter = camera.Parameters[PLCamera.PixelFormat];
                    widthSliderControl.Parameter = camera.Parameters[PLCamera.Width];
                    heightSliderControl.Parameter = camera.Parameters[PLCamera.Height];
                    if (camera.Parameters.Contains(PLCamera.GainAbs))
                    {
                        gainSliderControl.Parameter = camera.Parameters[PLCamera.GainAbs];
                    }
                    else
                    {
                        gainSliderControl.Parameter = camera.Parameters[PLCamera.Gain];
                    }
                    if (camera.Parameters.Contains(PLCamera.ExposureTimeAbs))
                    {
                        exposureTimeSliderControl.Parameter = camera.Parameters[PLCamera.ExposureTimeAbs];
                    }
                    else
                    {
                        exposureTimeSliderControl.Parameter = camera.Parameters[PLCamera.ExposureTime];
                    }*/
                }
                catch (Exception exception)
                {
                    ShowException(exception);
                }
            }
        }

        // 定时器跟新列表
        private void updateDeviceListTimer_Tick(object sender, EventArgs e)
        {
            UpdateDeviceList();
        }
    }
}
2.3 注释

(1)先加入上面的控件,修改控件名称一致
(2)按钮的点击事件、定时器定时、列表选取事件、窗体关闭等都要自己点击设置,不能照着代码全部复制,不然这些事件没有注册到Designer.cs中。也就是以下几个:
private void toolStripButtonOneShot_Click(object sender, EventArgs e){……}
private void toolStripButtonContinuousShot_Click(object sender, EventArgs e){……}
private void toolStripButtonStop_Click(object sender, EventArgs e){……}
private void deviceListView_SelectedIndexChanged(object sender, EventArgs ev){……}
private void updateDeviceListTimer_Tick(object sender, EventArgs e){……}
private void MainForm_FormClosing(object sender, FormClosingEventArgs ev){……}
(3)代码完整下载(包括其他功能,可启动运行):
https://download.csdn.net/download/chotin/12098938

  • 11
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果你想在 C# 中使用 Basler 相机,可以使用 Basler Pylon SDK。该 SDK 提供了一组功能强大的 API,可以方便地连接、配置和控制 Basler 相机,以及获取图像数据。 以下是使用 Basler Pylon SDK 连接 Basler 相机的基本步骤: 1. 下载并安装 Basler Pylon SDK。 2. 在 Visual Studio 中创建一个新的 C# 项目。 3. 在项目中添加对 PylonC.NET.dll 的引用。 4. 在代码中创建一个 Pylon.Camera 类的实例,并调用 Open() 方法打开相机。 ```csharp using PylonC.NET; ... // 创建相机实例 Pylon.Camera camera = new Pylon.Camera(); // 打开相机 camera.Open(); ``` 5. 配置相机的参数,例如曝光时间、增益等。 ```csharp // 设置曝光时间 camera.Parameters[PLCamera.ExposureTimeAbs].SetValue(10000); // 设置增益 camera.Parameters[PLCamera.GainRaw].SetValue(2.0); ``` 6. 开始采集图像数据。 ```csharp // 开始采集图像 camera.StreamGrabber.Start(); // 获取图像数据 Pylon.GrabResult result = camera.StreamGrabber.RetrieveResult(5000, Pylon.TimeoutHandling.ThrowException); if (result.GrabSucceeded) { // 处理图像数据 byte[] imageData = result.PixelData.ToArray(); // ... } // 停止采集图像 camera.StreamGrabber.Stop(); ``` 7. 最后,记得在程序退出时关闭相机。 ```csharp // 关闭相机 camera.Close(); ``` 以上是使用 Basler Pylon SDK 连接 Basler 相机的基本步骤,具体的应用场景和需求可能还需要进一步的配置和调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值