出力ストリーム、切り抜き、ズーム

出力ストリーム

カメラ サブシステムは、すべての解像度と出力形式について、ANativeWindow ベースのパイプラインでのみ動作します。一度に複数のストリームを構成して、GPU、動画エンコーダ、RenderScript、アプリ可視バッファ(RAW Bayer、処理された YUV バッファ、JPEG にエンコードされたバッファ)などの複数のターゲットに対して単一フレームを送信できます。

最適化のために、これらの出力ストリームは事前に構成する必要があり、一度に存在できるのは限られた数だけです。そうすることで、メモリバッファの事前割り当てとカメラ ハードウェアの構成が可能となり、複数の出力パイプラインもしくはさまざまな出力パイプラインが一覧の状態で送信されても、リクエストの実行が遅れたり、レイテンシが生じることがありません。

サポート済みのハードウェア レベルに応じて保証されるストリーム出力の組み合わせについては、createCaptureSession() を参照してください。

切り抜き

フルピクセル配列の切り抜き(デジタルズームや、FOV が小さい方が望ましいその他のユースケース)は、ANDROID_SCALER_CROP_REGION 設定を介して伝達されます。これはリクエストごとの設定であり、リクエストごとに変更できます。このことは、スムーズなデジタルズームを実現するうえで重要です。

領域はレクタングル(x, y, 幅, 高さ)で定義され、(x, y)はレクタングルの左上隅を表します。レクタングルはセンサー アクティブ ピクセル配列の座標で定義され、アクティブなピクセル配列の左上のピクセルが(0, 0)になります。したがって、幅と高さは ANDROID_SENSOR_ACTIVE_PIXEL_ARRAY 静的情報フィールドでレポートされるサイズ以下にする必要があります。許可されている最小の幅と高さは、ANDROID_SCALER_MAX_DIGITAL_ZOOM 静的情報フィールドで HAL によりレポートされます。このフィールドは、サポートされている最大ズーム倍率を示します。したがって、切り抜き領域の最小の幅と高さは次のようになります。

  {width, height} =
   { floor(ANDROID_SENSOR_ACTIVE_PIXEL_ARRAY[0] /
       ANDROID_SCALER_MAX_DIGITAL_ZOOM),
     floor(ANDROID_SENSOR_ACTIVE_PIXEL_ARRAY[1] /
       ANDROID_SCALER_MAX_DIGITAL_ZOOM) }

切り抜き領域に特定の要件を満たす必要がある場合(偶数の座標から開始し、幅と高さを偶数にする必要がある場合など)、HAL で必要な丸め処理を行い、出力結果のメタデータで使用される最終的な切り抜き領域を書き出す必要があります。同様に、HAL で動画の手ぶれ補正を実装する場合、結果の切り抜き領域を調整し、動画の手ぶれ補正が適用された後で実際に出力に含まれる領域を記述する必要があります。一般に、カメラを使用するアプリは、切り抜き領域、イメージ センサーの寸法、レンズ焦点距離に基づいて画角を決定できる必要があります。

切り抜き領域はすべてのストリームに適用されますが、切り抜き領域とは異なるアスペクト比を持つストリームもあるため、各ストリームに使用される正確なセンサー領域は、切り抜き領域より小さくなる場合があります。具体的には、定義された切り抜き領域を最小限に切り抜くことで、各ストリームでスクエア ピクセルとアスペクト比を維持する必要があります。ストリームのアスペクト比が切り抜き領域よりも広い場合、ストリームをさらに縦方向に切り抜き、ストリームのアスペクト比が切り抜き領域よりも狭い場合、ストリームをさらに横方向に切り抜く必要があります。

ストリームの切り抜き領域は、どのような場合でも、横方向または縦方向のいずれかで切り抜き領域全体の中央に配置されます。縦横の双方の向きで中央に配置されることはありません。

たとえば、2 つのストリームが 640x480 のストリーム(アスペクト比 4:3)と 1,280x720 のストリーム(アスペクト比 16:9)として定義されている場合に、3 メガピクセル(2,000 × 1,500 ピクセル配列)のセンサーを仮定すると、それぞれの切り抜き領域に対して見込まれる出力領域は以下のようになります。

切り抜き領域:(500, 375, 1000, 750)(アスペクト比 4:3)
640x480 のストリームの切り抜き:(500, 375, 1000, 750)(切り抜き領域に等しい)
1,280x720 のストリームの切り抜き:(500, 469, 1000, 562)

crop-region-43-ratio

図 1. アスペクト比 4:3

切り抜き領域:(500, 375, 1333, 750)(アスペクト比 16:9)
640x480 のストリームの切り抜き:(666, 375, 1000, 750)
1,280x720 のストリームの切り抜き:(500, 375, 1333, 750)(切り抜き領域に等しい)

crop-region-169-ratio

図 2.アスペクト比 16:9

切り抜き領域:(500, 375, 750, 750)(アスペクト比 1:1)
640×480 ストリームの切り抜き:(500, 469, 750, 562)
1,280x720 ストリームの切り抜き:(500, 543, 750, 414)

crop-region-11-ratio

図 3. アスペクト比 1:1

最後の例では、480p ストリームではなく 1,024x1,024 のスクエア アスペクト比のストリームを使用しています。
切り抜き領域:(500, 375, 1000, 750)(アスペクト比 4:3)
1,024x1,024 ストリームの切り抜き:(625, 375, 750, 750)
1,280x720 ストリームの切り抜き(500, 469, 1000, 562)

crop-region-43-square-ratio

図 4. アスペクト比 4:3、スクエア

再処理

RAW 画像ファイルは、RAW Bayer データを再処理することでサポートされます。このサポートにより、カメラ パイプラインで過去にキャプチャされた RAW バッファとメタデータ(過去に記録されたフレーム全体)を処理し、新しくレンダリングされた YUV または JPEG 出力を生成できるようになります。

ズーム

Android 11 以降を搭載したデバイスでは、アプリは ANDROID_CONTROL_ZOOM_RATIO 設定でカメラのズーム(デジタルおよび光学式)を使用できます。

ズーム倍率は、浮動小数点要素として定義されます。アプリは、切り抜きとズームに ANDROID_SCALER_CROP_REGION を使用する代わりに、ANDROID_CONTROL_ZOOM_RATIO を使用してズームレベルを制御し、水平方向と垂直方向の切り抜きに ANDROID_SCALER_CROP_REGION を使用して、アスペクト比をネイティブのカメラセンサーとは異なるものにします。

マルチカメラ システムには、レンズ焦点距離の異なる複数のレンズが含まれている場合があり、ユーザーはレンズを切り替えることで光学ズームを使用できます。次の状況で ANDROID_CONTROL_ZOOM_RATIO を使用すると、次のメリットがあります。

  • 広角レンズから望遠レンズへのズームイン: 浮動小数点比は、ANDROID_SCALER_CROP_REGION の整数値と比較して精度が高くなります。
  • 広角レンズから超広角レンズへのズームアウト: ANDROID_CONTROL_ZOOM_RATIO はズームアウト(<1.0f)をサポートしますが、ANDROID_SCALER_CROP_REGION はサポートしません。

説明のために、前のセクションで定義された同じ架空のカメラを使用して、異なるズームレベル、切り抜き領域、出力ストリームのシナリオをいくつか示します。

ズーム倍率: 2.0、元の視野の 1/4
切り抜き領域:(0, 0, 2000, 1500)(アスペクト比 4:3 )
640x480 のストリームの切り抜き:(0, 0, 2000, 1500)(切り抜き領域に等しい)
1,280×720 のストリームの切り抜き:(0, 187, 2000, 1125)

zoom-ratio-2-crop-43

図 5. ズーム 2.0、アスペクト比 4:3

ズーム倍率: 2.0、元の視野の 4/4
切り抜き領域:(0, 187, 2000, 1125)(アスペクト比 16:9)
640x480 のストリームの切り抜き:(250, 187, 1500, 1125)(ピラーボックス表示)
1,280x720 のストリームの切り抜き:(0, 187, 2000, 1125)(切り抜き領域に等しい)

zoom-ratio-2-crop-169

図 6. ズーム 2.0、アスペクト比 16:9

ズーム倍率: 0.5、元の画角の 4 倍(広角レンズからウルトラワイド レンズへの切り替え)
切り抜き領域:(250, 0, 1500, 1500)(アスペクト比 1:1)
640x480 のストリームの切り抜き:(250, 187, 1500, 1125)(レターボックス表示)
1,280x720 のストリームの切り抜き:(250, 328, 1500, 844)(レターボックス表示)

画像/zoom-ratio-0.5-crop-11

図 7. ズーム 0.5、アスペクト比 1:1

上のグラフからわかるように、切り抜き領域の座標系は、ズーム後の有効なズーム画角に変わり、次の寸法の長方形で表されます:(0, 0, activeArrayWith, activeArrayHeight)。同じことが AE / AWB / AF エリアと人間の顔にも当てはまります。この座標系の変更は、RAW キャプチャとそれに関連するメタデータ(intrinsicCalibrationlensShadingMap など)には適用されません。

上の例と同じ例を取り上げます。出力ストリーム #1(640x480)がビューファインダー ストリームであるとすると、次の 2 つの設定で 2 倍ズームを実現できます。

  • zoomRatio = 2.0scaler.cropRegion = (0, 0, 2000, 1500)
  • zoomRatio = 1.0(デフォルト)、scaler.cropRegion = (500, 375, 1000, 750)

アプリで android.control.aeRegions をビューファインダーの画角の左上隅に設定するには、android.control.aeRegions(0, 0, 1000, 750) に設定し、android.control.zoomRatio2.0 に設定します。または、アプリは android.control.zoomRatio1.0 の場合、android.control.aeRegions(500, 375, 1000, 750) の同等の領域に設定できます。