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がサポートする画像収集装置の数を表示し、装置の数を返します.採集カード(正確にはカメラ)の情報を取得し、
//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);
}