4.18. 複数のセンサー¶
ごく一部のOpenMV Camは、同じボード上に2つのイメージセンサーを組み合わせています -- 最も一般的なのはカラーカメラとFLIR® Lepton®サーマルセンサーの組み合わせですが、同じ構成はカラー+イベントのボードや、将来のあらゆるデュアルセンサーハードウェアにも当てはまります。各センサーは独自のピクセルアレイと独自の制御バスを持ち、独自のフレームレートで独自のパイプラインを動かします。CSI APIは、物理センサーごとに1つの CSI オブジェクトをアプリケーションがインスタンス化できるようにすることで、これらに対応するよう拡張されています。
4.18.1. どのセンサーを選択するか¶
CSI コンストラクタは、ボード上の特定のセンサーを指定する cid 引数を取ります。cid=-1(デフォルト)はプライマリセンサーを選択します。名前付きの cid 定数は、チップIDによってセカンダリを選択します:
import csi
csi_rgb = csi.CSI() # primary colour sensor
csi_thermal = csi.CSI(cid=csi.LEPTON) # FLIR® Lepton®
各インスタンスは独自の構成 -- ピクセルフォーマット、フレームサイズ、露出/ゲインの調整、フレームバッファプール -- を所有し、他方とは独立してリセット、構成、読み取りが行われます。サポートされるセカンダリセンサー用の定数(LEPTON、GENX320、および CSI リファレンスに列挙されているその他)は、アプリケーションがセカンダリポートに期待するチップを指定します。実際のチップが一致しない場合、ドライバは構築を失敗させます。
4.18.2. 両方のセンサーからのキャプチャ¶
各センサーは互いに独立してキャプチャパイプラインを動かします -- カラーセンサーが毎秒30フレームを供給する一方で、Lepton®は9フレームを供給するかもしれません。このミスマッチを扱う最も直接的な方法は、より高速なセンサーにループを駆動させ、より低速なセンサーをノンブロッキングで読み取り、準備ができているものは何でも受け取り、何もないときはその反復をスキップすることです:
import csi
csi_rgb = csi.CSI()
csi_thermal = csi.CSI(cid=csi.LEPTON)
csi_rgb.reset() # powers the rail, pulses RESET
csi_rgb.pixformat(csi.RGB565)
csi_rgb.framesize(csi.QVGA)
csi_thermal.reset(hard=False) # I2C reconfigure only
csi_thermal.pixformat(csi.GRAYSCALE)
csi_thermal.framesize(csi.QQVGA)
while True:
rgb_img = csi_rgb.snapshot() # blocks for next colour frame
thermal_img = csi_thermal.snapshot(blocking=False) # returns None if not ready
if thermal_img is not None:
# process aligned colour + thermal pair
pass
else:
# process colour only on this iteration
pass
ブロッキングの snapshot() がループのペースを決めます。ノンブロッキングのものは、前回の呼び出し以降に新しいサーマルフレームが到着していればその最新のものを返し、そうでなければ None を返します。アプリケーションはカラーセンサーのフレームレートで動き続け、Lepton®がサーマルフレームを生成するたびにそれを取得します。
逆のパターン -- 2つのブロッキングスナップショットを連続して -- も機能しますが、その場合ループは2つのセンサーのうちより低速な方のレートで動作し、より高速なセンサーのパイプラインは反復の間に停止します。アプリケーションの下流の処理が実際に駆動したいレートはどちらなのかを選んでください。
4.18.4. ストリームソースの選択¶
2つのセンサーを持つカメラは2つの CSI インスタンスを持ちますが、それらの間でストリームフレームバッファは依然として1つだけです。コンストラクタ引数で、どのセンサーのフレームがプレビューに供給されるかを選びます:
csi_rgb = csi.CSI() # primary
csi_thermal = csi.CSI(cid=csi.LEPTON,
stream=True) # preview source
stream=True は、名前付きのインスタンスをソースにします。stream= 引数がない場合、プライマリセンサー(cid=-1、デフォルト)がソースになります。セカンダリセンサーの cid= を指定して構築されたインスタンスは、stream=True が明示的に渡されない限りプレビュー上では無音のままです。選択されていないセンサーでの snapshot() の呼び出しは、依然として通常通りそのセンサーのフレームバッファにフレームをキャプチャします -- ただプレビューを更新しないだけです。