Halcon: Image Acquisition Callback
6097 ワード
ソースコードはHalcon/IACAllback(C#)から来ています.IA=Image Acquisition.
Halconの画像収集部をデバッグしようと、AVT Stringray F-201 Bのカメラを3つ持ってきてテストしたところ、コールバック関数部がサポートされていないため、プログラムが完全にオンになっていないことが分かった.
プログラム全体は、Show Available Device->init device->Start Acquire Thread->Show available Callback Type->Register Callback Type->Grab Image Start->Exit Programという論理に従っています.
1)ShowAvailableDevice:
halconがサポートする画像収集装置の数を表示し、装置の数を返します.採集カード(正確にはカメラ)の情報を取得し、
ソースコードはcInterface="GigEVision"で、カメラF-201 Bはサポートしていませんが、後で私は"GenICamTL"に変更すればいいです.ステートメント
i=0をとると、以下のカメラの情報が得られます(前の「1」は追加されています).
2)Init Device:
ユーザーの選択に応じて対応するカメラを開く
最初のパラメータnameは「GenICamTL」を選択します.そうしないと、例外が発生します.
3)Start Acquire Thread:
パラメータ付きスレッドを使用して画像を非同期で収集
入力したHTuple型のパラメータAcqHandleは上で選択したカメラを表し、ブール型の変数gThreadRunningはスレッドが動いているかどうかを表し、本体動作DoWork()は画像の非同期採集を完了する.
待機信号gAcqConditionなので、採集する動作はありません.
4)Show Available Callback Types:
カメラがサポートするコールバックタイプを読み込む
出力値Valueは配列で、次の文で結果を印刷します.
F-20 Bカメラでサポートされているすべてのコールバック(合計181個、個人的には属性と見なすことができるものが多いと思います)を取得します.
5)Register Callback Type:
ユーザが選択するCallback Typeとプログラムで規定するcallback(transfer_end,event_queue_overflow,device_lostなど)との比較により、いずれも満たされない場合はEventSelector,EventNotificationを含むパラメータを設定する必要がある.
次にExposureEnd,transfer_を登録するかどうかを判断します.endは、対応する登録を完了します.定義されたdelegate:
登録完了:
myContextは、ユーザーの選択を表す整数値(0,1,2)です.myContext=1または2を強制的に変更して、次のMyCallback Functionループを入れるようにしてみましたが、私の望み通りにはなりませんでした.プログラムによると、callback not supported.
MyCallbackFunctionの定義に戻ります.
前のステップで得られた181個のコールバックタイプを比較すると,これらと同じものは1個もなく,ハードウェアがサポートしていない可能性があることが分かった.
6)Grab Image Start:
競合を回避するために、ここでGrabとスレッド間のGrabはHalconの反発器Mutex(WindowsのMutexではありません)を使用しています.
ユーザーがEnterをクリックして採集を終了することを知っています.
7)Exit Program:
プログラムを終了するプロセスには、Callbackの登録をキャンセルすること、スレッドに終了信号を送信する.スレッドの終了を待つ;リソースをクリアします.
Halconの画像収集部をデバッグしようと、AVT Stringray F-201 Bのカメラを3つ持ってきてテストしたところ、コールバック関数部がサポートされていないため、プログラムが完全にオンになっていないことが分かった.
プログラム全体は、Show Available Device->init device->Start Acquire Thread->Show available Callback Type->Register Callback Type->Grab Image Start->Exit Programという論理に従っています.
1)ShowAvailableDevice:
halconがサポートする画像収集装置の数を表示し、装置の数を返します.採集カード(正確にはカメラ)の情報を取得し、
//HOperatorSet.InfoFramegrabber(cInterface, "device", out hv_Information, out hv_BoardList);
HOperatorSet.InfoFramegrabber("GenICamTL", "info_boards", out hv_Information, out hv_BoardList);
ソースコードはcInterface="GigEVision"で、カメラF-201 Bはサポートしていませんが、後で私は"GenICamTL"に変更すればいいです.ステートメント
hv_BoardList.TupleSelect(i).S
i=0をとると、以下のカメラの情報が得られます(前の「1」は追加されています).
1) | device:DEV_0xA4701130A5F3B | unique_name:DEV_0xA4701130A5F3B | interface:V
imba1394Interface_0x0 | producer:C:\Program Files\Allied Vision\Vimba_2.1\Vimba1
394TL\Bin\Win64\Vimba1394TL.cti | vendor:AVT | model:Stingray F201B | tl_type:II
DC | status:available
2)Init Device:
ユーザーの選択に応じて対応するカメラを開く
HOperatorSet.OpenFramegrabber("GenICamTL", 1, 1, 0, 0, 0, 0,
"default", -1, "default", -1, "false", "default",
gDevices[deviceNumber - 1], -1, -1, out AcqHandle);
最初のパラメータnameは「GenICamTL」を選択します.そうしないと、例外が発生します.
3)Start Acquire Thread:
パラメータ付きスレッドを使用して画像を非同期で収集
gWorkerThread = new Thread(new ParameterizedThreadStart(DoWork));
gWorkerThread.Start(AcqHandle);
gThreadRunning = true;
入力したHTuple型のパラメータAcqHandleは上で選択したカメラを表し、ブール型の変数gThreadRunningはスレッドが動いているかどうかを表し、本体動作DoWork()は画像の非同期採集を完了する.
static void DoWork(object AcqHandle)
{
HOperatorSet.LockMutex(gAcqMutex);
while (true)
{
HOperatorSet.WaitCondition(gAcqCondition, gAcqMutex);
if (!gThreadRunning || gCountCallbacks > cMaxGrabImage)
break;
Console.WriteLine("Thread specific calculations");
try
{
HOperatorSet.GrabImageAsync(out gImage, (HTuple)AcqHandle, -1);
}
catch (HalconException ex)
{
Console.WriteLine(ex.GetErrorMessage());
}
}
HOperatorSet.UnlockMutex(gAcqMutex);
Console.WriteLine("End acquisition thread
");
}
待機信号gAcqConditionなので、採集する動作はありません.
4)Show Available Callback Types:
カメラがサポートするコールバックタイプを読み込む
HOperatorSet.GetFramegrabberParam(hAcqHandle, "available_callback_types", out Value);
出力値Valueは配列で、次の文で結果を印刷します.
Console.WriteLine(i + 1 + ") " + Value.TupleSelect(i).S);
F-20 Bカメラでサポートされているすべてのコールバック(合計181個、個人的には属性と見なすことができるものが多いと思います)を取得します.
1) DeviceVendorName
2) DeviceModelName
3) DeviceFirmwareVersion
4) FirmwareVerMajor
5) FirmwareVerMinor
6) FirmwareVerBuild
7) DeviceMicrocontrollerVersion
8) DeviceSFNCVersionMajor
9) DeviceSFNCVersionMinor
10) DeviceSFNCVersionSubMinor
11) DeviceID
12) DeviceSerialNumber
... ...
180) [Stream]StreamAnnounceBufferMinimum
181) [Stream]DriverBuffersCount
5)Register Callback Type:
ユーザが選択するCallback Typeとプログラムで規定するcallback(transfer_end,event_queue_overflow,device_lostなど)との比較により、いずれも満たされない場合はEventSelector,EventNotificationを含むパラメータを設定する必要がある.
次にExposureEnd,transfer_を登録するかどうかを判断します.endは、対応する登録を完了します.定義されたdelegate:
static HalconDotNet.HalconAPI.HFramegrabberCallback delegateCallback = MyCallbackFunction;
登録完了:
IntPtr ptr = Marshal.GetFunctionPointerForDelegate(delegateCallback);
... ...
HOperatorSet.SetFramegrabberCallback(AcqHandle, gCallbackTypes[callback_number - 1], ptr, myContext);
myContextは、ユーザーの選択を表す整数値(0,1,2)です.myContext=1または2を強制的に変更して、次のMyCallback Functionループを入れるようにしてみましたが、私の望み通りにはなりませんでした.プログラムによると、callback not supported.
MyCallbackFunctionの定義に戻ります.
public static int MyCallbackFunction(IntPtr handle, IntPtr user_context, IntPtr context)
{
int int_context = context.ToInt32();
if (int_context == (int)myCallbackTypes.EXPOSURE_END ||
int_context == (int)myCallbackTypes.TRANSFER_END)
{
HOperatorSet.LockMutex(gAcqMutex);
HOperatorSet.SignalCondition(gAcqCondition);
gCountCallbacks++;
Console.WriteLine("Send signal to the worker thread");
HOperatorSet.UnlockMutex(gAcqMutex);
}
Console.WriteLine("User specific callback function executed");
return 0;
}
パラメータcontextはユーザの選択であり,選択を比較して採集スレッドに信号gAcqConditionを送信すれば採集を開始できる.前のステップで得られた181個のコールバックタイプを比較すると,これらと同じものは1個もなく,ハードウェアがサポートしていない可能性があることが分かった.
6)Grab Image Start:
競合を回避するために、ここでGrabとスレッド間のGrabはHalconの反発器Mutex(WindowsのMutexではありません)を使用しています.
static HMutex gAcqMutex;
... ...
gAcqMutex = new HMutex("", "");
... ...
HOperatorSet.LockMutex(gAcqMutex);
... ...
HOperatorSet.UnlockMutex(gAcqMutex);
ユーザーがEnterをクリックして採集を終了することを知っています.
7)Exit Program:
プログラムを終了するプロセスには、Callbackの登録をキャンセルすること、スレッドに終了信号を送信する.スレッドの終了を待つ;リソースをクリアします.
static void exitProgram(HTuple AcqHandle, bool init_device, bool reg_rallback, int callback_number)
{
HOperatorSet.LockMutex(gAcqMutex);
if (reg_rallback)
HOperatorSet.SetFramegrabberCallback(AcqHandle, gCallbackTypes[callback_number - 1], 0, 0);
HOperatorSet.UnlockMutex(gAcqMutex);
if (init_device)
{
gThreadRunning = false;
HOperatorSet.SignalCondition(gAcqCondition);
gWorkerThread.Join();
HOperatorSet.ClearMutex(gAcqMutex);
HOperatorSet.ClearCondition(gAcqCondition);
HOperatorSet.CloseFramegrabber(AcqHandle);
}
Environment.Exit(0);
}