注:博主看着另外一個博主的博客才有下面的一些總結,有興趣可以看一下: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:\Basler\Development\Assemblies\Basler.Pylon\x64\Basler.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(); } } } }