4.17. センサーのつまみ¶
pixformat() や framesize() のほかにも、CSI クラスはほぼすべてのアプリケーションが遅かれ早かれ必要とするセンサーごとの制御をいくつか公開しています。取り付け向き、露出、ゲイン、ホワイトバランス、そしていくつかのデバッグ補助です。それぞれが先に説明したセンサーの概念に直接対応しており、API はドライバが内部で行うレジスタ書き込みに対する Python のハンドルを提供しているにすぎません。
以下のメソッドはすべて基盤となるセンサーに対して作用します。いずれもセンサーの I2C 制御バス を介してレジスタ書き込みを送るため、コストはマイクロ秒単位で、新しい設定は次の露出から有効になります。通常は次の snapshot() です。
4.17.1. 向き¶
カメラは自分がどの向きで取り付けられたかを知りません。センサー側で適用される 2 つの反転フラグによって、ピクセルがチップから出る前に画像を正しい向きに直します:
csi0.hmirror(True)
csi0.vflip(True)
hmirror() は左右を反転し、vflip() は上下を反転します。両者を組み合わせると、実際に発生するケースに対応できます。上下逆さまに取り付けられた基板(両方のフラグが True)、表面反射ミラーの背後に置かれた基板(hmirror のみ)、あるいは下から反射した光景を見ている場合(vflip のみ)などです。
反転はセンサーの読み出しロジックで行われるため、CPU コストもメモリオーバーヘッドもありません。フレームはすでに正しい向きでフレームバッファに届きます。
4.17.2. 露出¶
露出は積分時間、つまり各ピクセルのフォトダイオードが行を読み出すまでに電荷を集める時間で、単位はマイクロ秒です。ドライバはセンサーの自動露出ループを実行した状態で始まるため、カメラは平均ピクセル値を目標値付近に保とうとします。このループを無効にすると、露出はアプリケーションが選んだ値に固定されます:
csi0.auto_exposure(False, exposure_us=8000)
固定露出は、シーンの明るさが安定していて、アプリケーションが予測可能なモーションブラーや、しきい値処理のためにフレーム間で一定の輝度を必要とする場合に適した選択です。現在の露出を読み返すには(ループが設定したかアプリケーションが設定したかに関わらず)別の呼び出しを使います:
us = csi0.exposure_us()
auto_exposure() を True で、露出値を指定せずに呼び出すと、制御がループに戻されます。
4.17.3. ゲイン¶
ゲインは、ピクセル電圧が ADC に到達する前にかけられる増幅で、単位はデシベルです。露出と同様に、ドライバは自動ゲインループがオンの状態で始まります。よく使われるパターンが 2 つあります。上限を制限すると、ループは照明に適応しつつも、暗いシーンでノイズを際限なく増幅することを防げます:
csi0.auto_gain(True, gain_db_ceiling=16)
ゲインを固定するのは、アプリケーションが露出も固定する場合に適した手法です。ゲインの安定性は、カラートラッキングのようにフレーム間でピクセル値を比較するアプリケーションにとって重要です:
csi0.auto_gain(False, gain_db=0)
現在のゲインは gain_db() を通じて読み返せます。アプリケーションが自動ゲインを無効にするときは、自動ホワイトバランスと自動露出も無効にすべきです。そうしないと、依然として動作している制御ループが画像を引き回し、固定ゲインの効果を台無しにしてしまいます。
4.17.4. ホワイトバランス¶
ホワイトバランスは、どのような色の光の下でも白い物体が白く見えるように、ISP がデベイヤー段から出てくる赤・緑・青の各チャンネルに適用するチャンネルごとのゲインです。自動ホワイトバランスループは、ISP が各フレームで収集する領域ごとの 統計 からこれら 3 つのゲインを計算し、次のフレームで適用します。
ほとんどのアプリケーションはループを動作させたままにします。カラートラッキングはよくある例外です。これらのゲインはループが色のついた物体を追いかけるために調整するものでもあるため、アプリケーションが赤いブロブを見つけようとしている場合、ループは静かに赤チャンネルを暗くし、ブロブはマッチしなくなります。ループをロックすればこれを解決できます:
csi0.auto_whitebal(False)
ボード間やセッション間で同じゲインを使う再現性のあるカラーキャリブレーションには、デシベル単位の明示的な (r, g, b) タプルを渡します:
csi0.auto_whitebal(False, rgb_gain_db=(0.0, 0.0, 0.0))
現在のゲインは rgb_gain_db() を通じてタプルとして読み返せます。
4.17.5. フレームレートの上限¶
センサーはデフォルトでネイティブのフレームレートで動作します。ほとんどの部品で毎秒 30〜60 フレーム、高速センサーではフレームサイズが十分に小さい場合ははるかに高くなります。レートに上限を設けると、アプリケーションは下流の処理が追いつける速度までカメラを制限できます:
csi0.framerate(15)
ハードウェアレート制御に対応したセンサーでは、この呼び出しはフレームごとの露出予算も延ばすため、低照度で役立つことがあります。それ以外のセンサーでは、ドライバは単にフレームバッファのレベルで余分なフレームをスキップします。
4.17.6. テストパターン¶
カラーバーのテストパターンはほとんどのセンサーに組み込まれており、撮像の問題と出力の問題を切り分けるのに役立ちます。これをオンにすると、フォトダイオードアレイをバイパスして、固定パターンを同じピクセルデータパスに送ります:
csi0.colorbar(True)
テストパターンが正しく見えるのに実写画像が正しくない場合、不具合は光学系かセンサーのアナログフロントエンドにあります。テストパターンまで壊れている場合は、問題はピクセルデータバス上のどこか、または pixformat() / framesize() の設定にあります。実写画像に戻すには False を渡します。
特定のセンサーファミリーに固有の制御を公開するセンサー固有の ioctl() コマンドを含む完全な API については、csi.CSI を参照してください。