Basler
2. One shot Grab
컨트롤Z
2024. 2. 11. 12:27
2.1 Winform 프로젝트 만들기
- Basler 솔루션 안에 BaslerOneShotGrab이라는 이름으로 Windows Forms 앱 (.NET Framework) 프로젝트를 만들고 C#작업환경 만들기를 참조하여 Basler.Pylon.dll을 참조 추가한다.
2024.02.08 - [Basler] - 1. c# 작업 환경 만들기
1. c# 작업 환경 만들기
Basler 홈페이지에서 제공하는 Pylon Viewer를 설치한다 현재 내가 PC에 설치한 6.2.0 기준으로 (Pylon Viewer 설치 경로)\pylon 6\Development\Assemblies\Basler.Pylon\ 하위에 x64, x86폴더로 나눠져 있고 이중에 자기 os
machinevision-story.tistory.com
2.2 UI 디자인
- 도구 상자에서 Button 3개와 PictureBox 1개를 드래그 하여 Form1에 위치 시킨다
- button과 Name속성과 button의 Text속성을 아래 표와 같이 변경한다.
컨트롤 이름 | 속성 | 값 |
button1 | Name | BtnOpen |
Text | Connect | |
button2 | Name | BtnGrab |
Text | Grab | |
button3 | Name | BtnClose |
Text | Disconnect |
2.3 코드 입력
- BtnOpen, BtnGrab, BtnClose를 더블클릭하여 이벤트를 생성한 후 코드를 입력한다.
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
using Basler.Pylon;
namespace BaslerOneShotGrab
{
public partial class Form1 : Form
{
private Camera camera;
private PixelDataConverter converter;
public Form1()
{
InitializeComponent();
camera = new Camera();
converter = new PixelDataConverter();
}
private void BtnOpen_Click(object sender, EventArgs e)
{
camera.Open();
}
private void BtnGrab_Click(object sender, EventArgs e)
{
camera.StreamGrabber.Start();
IGrabResult grabResult = camera.StreamGrabber.RetrieveResult(5000, TimeoutHandling.Return);
if (grabResult.GrabSucceeded)
{
Bitmap bitmap = new Bitmap(grabResult.Width, grabResult.Height, PixelFormat.Format32bppRgb);
BitmapData bmpData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
IntPtr ptrBmp = bmpData.Scan0;
converter.OutputPixelFormat = PixelType.BGRA8packed;
converter.Convert(ptrBmp, bmpData.Stride * bitmap.Height, grabResult);
bitmap.UnlockBits(bmpData);
Bitmap bitmapOld = pictureBox1.Image as Bitmap;
pictureBox1.Image = bitmap;
if (bitmapOld != null)
{
// Dispose the bitmap.
bitmapOld.Dispose();
}
}
camera.StreamGrabber.Stop();
}
private void BtnClose_Click(object sender, EventArgs e)
{
camera.Close();
}
}
}
2.4 구문 설명
camera = new Camera();
- 카메라의 인스턴스를 생성한다.
- 매개변수를 넣지 않으면 첫번째 장치를 선택해서 생성한다.
camera.Open();
- 카메라를 연결한다.
camera.StreamGrabber.Start();
- 이미지 취득을 시작한다.
IGrabResult grabResult = camera.StreamGrabber.RetrieveResult(5000, TimeoutHandling.ThrowException);
- 그랩이 완료 될 때까지 대기한 후 그랩 결과를 반환하는 함수다.
- 첫번째 매개변수 : 그랩 완료 타임 아웃 변수, 단위 ms (ex. 5000이면 5000ms이후 그랩이 완료되지 않으면 event발생)
- 두번째 매개변수 : 그랩 타임 아웃이 지난 후 발생한 이벤트 처리
- TimeoutHandling.Return : 반환 값을 null처리하고 완료한다.
- TimeoutHandling.ThrowException : 예외를 발생시킨다.
if (grabResult.GrabSucceeded)
- 그랩이 성공적으로 완료되면 반환값인 IGrabResult의 GrabSucceeded값이 true가 된다.
Bitmap bitmap = new Bitmap(grabResult.Width, grabResult.Height, PixelFormat.Format32bppRgb);
BitmapData bmpData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
IntPtr ptrBmp = bmpData.Scan0;
- 이 구문은 일반적으로 많이 쓰이는 구문으로 Bitmap에서 비트맵 픽셀 데이터의 포인터 주소를 가져올 수 있다.
- bitmap lockbits를 구글링하면 자세한 정보를 얻을 수 있다.
private PixelDataConverter converter;
converter = new PixelDataConverter();
converter.OutputPixelFormat = PixelType.Mono8;
converter.Convert(ptrBmp, bmpData.Stride * bitmap.Height, grabResult);
- PixelDataConverter는 Basler.Pylon.dll이 들어있는 클래스로써 소스이미지를 변환하여 새 이미지를 만들 때 쓰인다.
- Convert() : 그랩 데이터를 새로 만든 Bitmap에 복사하는 함수
- 첫번째 매개변수 : 결과 bitmap의 픽셀 데이터 포인터
- 두번째 매개변수 : 픽셀 데이터의 크기 ( 결과 bitmap의 stride * height )
- 세번째 매개변수 : 그랩 데이터
bitmap.UnlockBits(bmpData);
- lockbits함수를 사용하여 lock걸린 메모리 영역을 unlock하는 함
Bitmap bitmapOld = pictureBox1.Image as Bitmap;
pictureBox1.Image = bitmap;
if (bitmapOld != null)
{
bitmapOld.Dispose();
}
- Bitmap을 pictureBox1에 넣기 전에 기존에 pictureBox1에 있던 Bitmap을 빼서 Dispose하는 구문
- bitmap을 dispose하지 않고 새 bitmap을 넣게 되면 메모리 누수가 일어난다.
camera.StreamGrabber.Stop();
- 그랩을 멈춘다.
camera.Close();
- 카메라를 닫는 함수.
- 종료하기 전에 항상 호출해야 한다.
2.5 결과
Connect → Grab → Disconnect