using System;
using HalconDotNet;
public sealed class CoaxpressLineCamera : IDisposable
{
private HTuple? _acqHandle;
public void Open(string deviceName)
{
try
{
// GenICamTLデバイスをオープン
HOperatorSet.OpenFramegrabber(
"GenICamTL", // Name
0, // HorizontalResolution
0, // VerticalResolution
0, // ImageWidth
0, // ImageHeight
0, // StartRow
0, // StartColumn
"progressive", // Field
-1, // BitsPerChannel
"default", // ColorSpace
-1, // Generic
"false", // ExternalTrigger
"default", // CameraType
deviceName, // Device
0, // Port
-1, // LineIn
out HTuple handle);
_acqHandle = handle;
// 撮像開始前にROI・バッファサイズを設定
ConfigureImageSize(width: 100, height: 100);
}
catch
{
Close();
throw;
}
}
private void ConfigureImageSize(int width, int height)
{
EnsureOpened();
// 撮像中の場合に備えて停止を試みる
TrySetParameter("do_abort_grab", 1);
/*
* ラインカメラ本体側
*
* Width = 1ライン当たりの画素数
* Height = 通常1固定なので変更しない
*/
HOperatorSet.SetFramegrabberParam(
_acqHandle!,
"Width",
width);
/*
* Euresys Data Stream側
*
* BufferHeight = 1枚の画像としてまとめるライン数
*/
HOperatorSet.SetFramegrabberParam(
_acqHandle!,
"[Stream]BufferHeight",
height);
// 設定された実値を確認
PrintParameter("Width");
PrintParameter("Height");
PrintParameter("[Stream]BufferHeight");
PrintParameter("image_width");
PrintParameter("image_height");
}
public HObject GrabOneImage()
{
EnsureOpened();
// 非同期取得の準備
HOperatorSet.GrabImageStart(_acqHandle!, -1);
// 100ラインが蓄積されると、100×100画像として返る想定
HOperatorSet.GrabImageAsync(
out HObject image,
_acqHandle!,
-1);
// 実際に返されたHALCON画像のサイズを確認
HOperatorSet.GetImageSize(
image,
out HTuple actualWidth,
out HTuple actualHeight);
Console.WriteLine(
$"取得画像サイズ: {actualWidth.I} × {actualHeight.I}");
if (actualWidth.I != 100 || actualHeight.I != 100)
{
image.Dispose();
throw new InvalidOperationException(
$"期待サイズは100×100ですが、" +
$"{actualWidth.I}×{actualHeight.I}が返されました。");
}
return image;
}
private void PrintParameter(string parameterName)
{
try
{
HOperatorSet.GetFramegrabberParam(
_acqHandle!,
parameterName,
out HTuple value);
Console.WriteLine($"{parameterName} = {value}");
}
catch (HOperatorException ex)
{
Console.WriteLine(
$"{parameterName}: 取得不可 " +
$"HALCON Error={ex.GetErrorCode()}, {ex.Message}");
}
}
private void TrySetParameter(string parameterName, HTuple value)
{
try
{
HOperatorSet.SetFramegrabberParam(
_acqHandle!,
parameterName,
value);
}
catch (HOperatorException)
{
// 現在Grab中でない場合などは失敗しても問題ないため無視
}
}
private void EnsureOpened()
{
if (_acqHandle is null || _acqHandle.Length == 0)
{
throw new InvalidOperationException(
"カメラがOpenされていません。");
}
}
public void Close()
{
if (_acqHandle is null || _acqHandle.Length == 0)
return;
try
{
TrySetParameter("do_abort_grab", 1);
HOperatorSet.CloseFramegrabber(_acqHandle);
}
finally
{
_acqHandle.Dispose();
_acqHandle = null;
}
}
public void Dispose()
{
Close();
}
}