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

1、简介

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

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

2、basler C# demo

2.1 使用到的控件

功能和控件 控件名称
拍照 button toolStripButtonOneShot
录像 button toolStripButtonContinuousShot
停止 button toolStripButtonStop
相机列表 listview UpdateDeviceList
定时器 timer updateDeviceListTimer
窗体form MainForm

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

你可能感兴趣的:(#,芯片检测机,#,basler相机)