注:博主看着另外一个博主的博客才有下面的一些总结,有兴趣可以看一下:https://blog.csdn.net/qq_39930578/article/details/87897257
每个相机基本都有自己带的SDK 初学者看一下自己后期需要使用到什么相机就学那个列:海康、巴勒斯......前提是相机方提供的sdk里有C#的接口。
调用巴勒斯的相机使用sdk Basler产品文档:https://zh.docs.baslerweb.com/
通用套路:1.初始化相机 2.打开相机 3.设置配置 4.图像抓取 5.停止抓取 6.图片保存
采集相机的几种方式:1.多线程采集 2.setTime 定时器采集 3.回调函数 等等..
1.下载安装Basler程序:详情请看一下这个(前进ing 博主)写的:https://blog.csdn.net/weixin_41650642/article/details/81129978
2.安装好之后里面有对应的Basler.Pylon.dll文件需要在vs中引入这个dll文件大致路径是这样的D:BaslerDevelopmentAssembliesBasler.Pylonx64Basler.Pylon.dll 这个是我电脑上的路径仅供参考
3.有什么不对的多去博客里面看看,手动滑稽! 进代码 有详细注释,有什么不对的地方希望大佬们指出
using Basler.Pylon; using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; namespace CSharpAndSDK { static class Program { /// <summary> /// 应用程序的主入口点。 /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } } public class baslerCamcs { //连接相机的个数 public int CameraNumber = CameraFinder.Enumerate().Count; //委托+事件=回调函数,用于传递相机抓取的图像 public delegate void CameraImage(Bitmap bmp); public event CameraImage CameraImageEvent; //放出一个Camera Camera camera; //basler里将相机采集到的图像转换成位图 PixelDataConverter pxConvert = new PixelDataConverter(); //控制相机采集图片的过程! bool Graber = true; //第一步初始化相机 所用的全是camera里的事件然后绑定自己写好的事件 public void CameraInit() { //相当于初始化了一下相机的动态链接库 可以调用Camera里面的东西了 camera = new Camera(); //自由连接模式 //当连接到相机时自动应用此配置 //打开后,将其添加到Basler.Pylon.ICamera中。在打电话之前,摄像头打开了活动 camera.CameraOpened += Configuration.AcquireContinuous; //断开连接事件 camera.ConnectionLost += Camera_ConnectionLost; //抓取开始事件 camera.StreamGrabber.GrabStarted += StreamGrabber_GrabStarted; //抓取图片事件 camera.StreamGrabber.ImageGrabbed += StreamGrabber_ImageGrabbed; //抓取结束事件 camera.StreamGrabber.GrabStopped += StreamGrabber_GrabStopped; //打开相机 //StreamGrabber_GrabStarted //StreamGrabber_GrabStopped camera.Open(); } /// <summary> /// 停止抓取 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void StreamGrabber_GrabStopped(object sender, GrabStopEventArgs e) { Graber = false; } /// <summary> /// 抓取图片 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void StreamGrabber_ImageGrabbed(object sender, ImageGrabbedEventArgs e) { IGrabResult grabResult = e.GrabResult; if (grabResult.IsValid) { if (Graber) { //委托就用到了! CameraImageEvent(GrabResult2Bmp(grabResult)); } } } /// <summary> /// 开始抓取 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void StreamGrabber_GrabStarted(object sender, EventArgs e) { Graber = true; } /// <summary> /// 断开连接 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Camera_ConnectionLost(object sender, EventArgs e) { try { //停止连接 camera.StreamGrabber.Stop(); //释放相机资源 DestroyCamera(); } catch (Exception) { return; } } /// <summary> /// 释放相机 /// </summary> public void DestroyCamera() { if (camera != null) { camera.Close(); camera.Dispose(); camera = null; } else { return; } } /// <summary> /// 将相机转换成图像转成Bitmap /// </summary> /// <param name="grabResult"></param> /// <returns></returns> Bitmap GrabResult2Bmp(IGrabResult grabResult) { // PixelFormat format:新的像素格式 System.Drawing.Bitmap。 这必须指定一个值,开头 Format。(参1:图宽,参2:图高,参3:像素格式) Bitmap b = new Bitmap(grabResult.Width, grabResult.Height, PixelFormat.Format32bppArgb); //BitmapData:指定位图像的属性 BitmapData bitmapData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, b.PixelFormat); //PixelType.BGRA8packed:抓取结果返回像素类型,由图像处理支持类使用 pxConvert.OutputPixelFormat = PixelType.BGRA8packed; IntPtr bmpIntpr = bitmapData.Scan0; pxConvert.Convert(bmpIntpr, bitmapData.Stride * b.Height, grabResult); b.UnlockBits(bitmapData); return b; } public void OneShot() { if (Graber) { //PLCamera:所有可用于basler摄像机设备dByStre的参数名称列表 SingleFrame:启用单帧采集模式。 camera.Parameters[PLCamera.AcquisitionMode].SetValue(PLCamera.AcquisitionMode.SingleFrame); camera.StreamGrabber.Start(1, GrabStrategy.OneByOne, GrabLoop.ProvidedByStreamGrabber); } } public void KeepShot() { //Continuous:启用连续采集模式。 camera.Parameters[PLCamera.AcquisitionMode].SetValue(PLCamera.AcquisitionMode.Continuous); //GrabStrategy.OneByOne:默认的抓取策略 //GrabLoop.ProvidedByStreamGrabber:定义了额外线程的使用 camera.StreamGrabber.Start( GrabStrategy.OneByOne, GrabLoop.ProvidedByStreamGrabber); } public void Stop() { if (camera != null) { //流抓取停止 camera.StreamGrabber.Stop(); } else { MessageBox.Show("该相机已停止抓取"); } } } }
下面是窗体部分:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Net.Http; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace CSharpAndSDK { public partial class Form1 : Form { public baslerCamcs camera { get; set; } = new baslerCamcs(); public Form1() { InitializeComponent(); //委托 camera.CameraImageEvent += Camera_CameraImageEvent; } private void Camera_CameraImageEvent(Bitmap bmp) { //使用委托进行跨线程交互 防止线程卡死状态在Invoke前面加一个Begin pictureBox1.BeginInvoke(new MethodInvoker(delegate { Bitmap old = pictureBox1.Image as Bitmap; pictureBox1.Image = bmp; if (old != null) old.Dispose(); })); } //拍一张 private void button1_Click(object sender, EventArgs e) { camera.OneShot(); } //停止 private void button2_Click(object sender, EventArgs e) { camera.Stop(); } /// 连续拍 private void button3_Click(object sender, EventArgs e) { camera.KeepShot(); } //当前窗体关闭的时候引发的释放相机 private void Form1_FormClosed(object sender, FormClosedEventArgs e) { camera.DestroyCamera(); } void Unanble() { this.button1.Enabled = false; this.button2.Enabled = false; this.button3.Enabled = false; } private void Form1_Load(object sender, EventArgs e) { //如果连接相机个数大于0的话 初始化之前写的CameraInit(); if (camera.CameraNumber > 0) { camera.CameraInit(); } else { MessageBox.Show("未连接到相机"); Unanble(); } } } }