非同期イメージ パイプラインの同期

オペレータの種類と同期に関する実践的なガイダンスについては、Operator Types and Synchronizationチュートトリアルを参照してください。

カメラの同期

VisualAppletsの強力な機能の1つに、異なるカメラソースからの画像を組み合わせる機能があります。 以下では、次の方法について学習します。

  1. カメラソース間で切り替える
  2. 2台のカメラの画像をオーバーレイする
  3. カメラ画像を多重化する
  4. 2台のカメラの画像をスティッチングする

2台のカメラ間の切り替え

2台のカメラの間で切り替えるには、2つのカメラモジュールを含むシンプルなデザインが必要です。 VisualAppletsでは、OperatorのSourceSelector('SourceSelector'を参照)を使用して、2つの非同期ソース間で切り替えることができます。 このOperatorを使用すると、一方の入力のデータを破棄しながら、もう一方の入力を選択できます。 いずれかの入力が選択されると、他の入力はTrash Operatorに接続されているかのように動作します。 取り込みの実行中に入力を切り替えることが可能です。Operatorは新しいフレームの開始時に切り替わります。 両方の入力のフレームレートと画像サイズが同じである必要はありません。

2台のカメラ間で切り替えるためのVisualAppletsデザイン

図 208:2台のカメラ間で切り替えるためのVisualAppletsデザイン


2台のカメラソースからの画像データの結合 - オーバーレイブレンドの構築

続いて、両方のカメラの画像データを組み合わせる方法について説明します。 この例では、オーバーレイブレンドを使用して両方の画像を組み合わせます。

この例の仕様は次のとおりです。

  • カメラ:ベースコンフィギュレーションモードの2台のCameraLink RGBエリアスキャンカメラ
  • 解像度:1024 x 1024 ピクセル
  • オーバーレイブレンド:

    式 1. オーバーレイブレンド


  1. 基本Operator

    次の図に示すように、デザイン内の基本Operatorから始めます。 すべてのデフォルトパラメータとリンクプロパティを使用できます。

  2. 同期化

    次に、両方のカメラのデータストリームを同期させる必要があります。 これを行うには、SYNC Operatorを使用します。 SYNC Operatorは、出力が完全に同期するように入力を制御します。 ご覧のとおり、同期の前に2つのバッファモジュールを使用しています。 両方のカメラが100%同期していることを保証できないため、これらを使用する必要があります。

    画像データの同期を行っても、いくつかの制約に注意する必要があります。

    • 両方のカメラのフレーム数(つまりフレームレート)は同じである必要があります。 一方のカメラのフレームレートがもう一方のカメラよりも高い場合、一方のImageBufferモジュールがいずれかの画像を保存する必要があり、 オーバーフロー状態になる可能性があります。 したがって、長時間の取り込みでは、両方のカメラが同じフレームレートを使用してフレームを取り込む必要があります。 トリガーシステムを使用すると、これを確実に行うことができます。

    • 両方のカメラのROIの画像サイズと画像位置が異なる場合があります。 SYNC Operatorは、そのパラメータ設定に応じて、小さい画像を大きい画像に自動的に拡大するか、大きい画像を切り取ります。 詳細については、SYNC Operatorの説明を参照してください:('SYNC')
  3. オーバーレイブレンド

    最後の手順は、両方の画像を組み合わせるためのオーバーレイブレンドを実装することです。 利便性を高めるため、オーバーレイブレンドの実装には階層ボックスを使用します。

    オーバーレイブレンドは、すべてのカラーコンポーネントに個別に適用する必要があります。 したがって、リンクを3つのすべてのカラーコンポーネントに分割する必要があります。 オーバーレイブレンドは、再び階層ボックス内に配置されます。 したがって、現在の階層ボックス内には3つの階層ボックスが存在します。 コピーアンドペーストを使用して、カラーコンポーネントごとにボックスを複製できます。

    VisualAppletsのOperatorを使用して上記の方程式を実現する方法はさまざまです。 一般に、実装する前に、FPGAで使用できるように常方程式を適応および最適化する必要があります。

    この方程式には、定数値によるいくつかの乗算と除算が含まれています。 これらの演算はVisualAppletsで使用できますが、FPGA上で非常に効率的に実装することはできません。 乗算または除算を2のべき乗の乗算として記述できる場合は、実装に簡単なビットシフトを使用できます。 ビットシフトに必要なリソースはゼロです! 簡略化します

    を

    これは7ビットの単純な右シフトであり、つまり下位7ビットを破棄します。

    次に、数式内には255からColorAを引くような部分があります。 これは単純な色の反転です。白は暗くなり、暗い部分は白くなります。 値の反転は、各ビットの単純な反転を使用して行うこともできます。 これにより、最終的に数式を次のように書き直すことができます:

    数式 2. FPGA実装のための最適化されたオーバーレイブレンド


    これで実装を開始できます。 数式内の残りの演算は、VisualAppletsオペレータとして利用可能です。 以下のものが必要になります:

    • IF

    • 反転用の NOT

    • 2^7で除算するための ShiftRight

    • 乗算用の HWMULT

      HWMULTのほかに、VisualAppletsには MULT オペレータも含まれています。 これらは同じ動作をしますが、HWMULT はFPGA内の専用乗算器を使用するため、必要なリソースが大幅に少なくなります。

    • ビット深度の制限には、CastBitWidth オペレータが必要になります。 このオペレータを使用すると、MSBを破棄して9ビットから8ビットに切り替えることができます。 式から、255を超える値が存在しないことがわかります。

  4. シミュレーションを使用した検証

    1. VisualAppletsのシミュレーションを使用して、オーバーレイブレンドの機能を簡単に検証できます。 2つのシミュレーションソースを使用して、両方のカメラの画像を注入します。 任意のリンクにシミュレーションプローブを配置します。 シミュレーション結果には、両方の画像のオーバーレイが表示されます。 必要に応じて、階層ボックス内のオーバーレイの中間結果を確認することもできます。

    2. シミュレーションはアプレットの機能部分のみを反映し、タイミングは反映しないため、シミュレーションによる同期の検証はできません。 ハードウェアでの検証が必要です。
  5. トリガーの追加

    前述のように、いずれかのバッファでのオーバーフローを回避するため、両方のカメラを同じフレームレートで動作させる必要があります。 これはトリガーシステムを使用することで簡単に解決できます。

2台のカメラの画像の多重化

VisualAppletsでの画像またはラインのマルチプレックスは非常に簡単です。 2台のカメラの画像をマルチプレックスする例から始めます。 つまり、同じDMAチャネルを使用して、カメラAとカメラBの画像を交互に出力したい場合です。

  1. 基本Operator

    2つのカメラモジュール、2つのバッファ、1つのDMAを使用する2台のカメラ用の標準デザインが必要になります。

  2. 画像のマルチプレックス

    画像をマルチプレックスするには、InsertImageオペレータを使用します。 このオペレータは、入力の画像を順番に転送します。 たとえば、2つの入力を使用する場合、オペレータは入力 0、1、0、1、0、1、... の画像を転送します。 したがって、1つの入力が処理された後、次の入力が使用されます。 そのため、両方の入力におけるフレーム数が同じであること、つまり入力が同じフレームレートを持つことが求められます。

    お気づきのように、挿入の前に画像バッファモジュールを配置しています。これは、InsertImageオペレータ自体にはバッファがないためです。 入力0の画像が転送されている間、入力1はブロックされるため、データの損失を防ぐためにカメラ画像をバッファリングする必要があります。

    各入力(I0、I1、…)に対して、オペレータはIns0、Ins1、…と呼ばれる2番目の入力を提供します。この入力は、画像を使用するか破棄するかを制御するための制御入力です。したがって、Ins入力に値0が指定されている場合は入力がスキップされ、値1が指定されている場合は使用されます。入力グループIとInsは同期している必要があります。つまり、任意のO型オペレータのネットワークを介して同じM型オペレータによってソースされる必要があります。詳細については、 「オペレータの種類」を参照してください。両方の入力が同期しているため、同じ画像サイズである必要があります。 InsertImage Ins入力の最初のピクセルを使用して、画像を使用するか破棄するかを決定します。前のスクリーンショットで示したように、 CONST演算子を使用して画像の使用を有効にしました。挿入を有効にするには、 CONST演算子の出力リンクビット深度を1ビットに、パラメータ「Value」を1に設定します。

    ご注意ください:いずれかのIns入力の値がゼロの場合でも、オペレータはこの入力上の画像を処理する必要があります。 値がゼロであることは、画像を提供する必要がないことを意味するものではありません。入力で画像が提供されない場合、オペレータは画像が利用可能になるまで待機します。

    前述のように、一度に開かれる入力は常に1つであり、他の入力はブロックされます。 画像は、異なるバッファなどから非同期でソース供給される必要があります。 次の図には、機能しない2つの構成が示されています。 アプレットが自己ブロックしているため、結果は得られません。これは「デッドロック」と呼ばれる状態です。

    InsertImageを使用したデッドロック構成

    図 209. InsertImageを使用したデッドロック構成


    一方の入力がアクティブな間に、停止した入力の一方をバッファリングできるかどうかを常に確認してください。 デッドロック状況はDRCやシミュレーションでは検出できないことに注意してください。 デッドロックの詳細については、「タイミング同期」を参照してください。

2台のカメラのスティッチング

前のセクションでは、2台のカメラの画像を多重化しました。ステッチングもほぼ同じ方法で行われます。 代わりにInsertLineオペレータを使用し、AppendLineオペレータを使用して連続する2つのラインを追加する必要があります。

InsertLineは、最初に両方の入力のラインを多重化し、その後に2つのラインを追加する必要があります。

もちろん、最後の2つの例でも同じ画像ソースを使用することが可能です。 注意すべき点は、挿入前に十分なバッファがあることだけです。 画像を挿入するには、画像全体をバッファリングする必要があります。 ラインを複製するには、一方のパスで同じラインが処理されている間に、単にラインの1つをバッファリングするだけです。 わずか数ラインのみをバッファリングするには、ImageFifoオペレータを使用できます。このオペレータは、フレームグラバーのDRAM Memoryを使用しません。 代わりに、FPGA内部のBlockRAM Memoryを使用します。 FIFOが最大1ラインを格納するように設定します。 次の例では、画像ラインを複製しており、その複製は反転されています。 したがって、結果は左側が元の画像、右側が反転(ネガティブ)バージョンになります。

ライン複製

図 210:ライン複製