第16章:ホワイトバランスと色
明るさ(露出)と鮮明さ(フォーカス)をマスターしました。次は画像の見た目、つまり色調を制御する番です。
温かみのある白熱灯の下で白い紙を撮影すると、ランプの黄色やオレンジ色の光が紙に当たり、センサーはそれをオレンジ色として捉えます。人間の脳はこれを瞬時に補正して「白い紙」として認識し続けますが、センサーの生データにはオレンジ色として記録されます。
ホワイトバランス (White Balance, WB) は、光源の色を補正して、無彩色の白が白く見えるようにするカメラの処理プロセスです。これを誤ると、写真全体に不自然な色かぶり(オレンジすぎ、青すぎ、緑すぎなど)が発生します。
Android Camera Parameters アプリでは、すべての AWB プリセットをライブグリッドビューで確認したり、マニュアルゲインのスライダーを操作したりできます。この章で実装する内容をアプリで実際に体験してみてください。
色温度:暖色から寒色へのスペクトル
光源は、ケルビン (K) 単位の色温度で表されます。このスケールは、同じ色で発光する理論上の「黒体放射体」の温度を表しています。
直感とは逆のルール: 暖色系の光 = 低い数値(1800Kのキャンドルは非常にオレンジ)。寒色系の光 = 高い数値(10000Kの空は非常に青)。
オートホワイトバランスの役割は、シーンの統計情報から光源を推測し、その色かぶりを差し引いて、白い物体が白く見えるようにすることです。
Camera2 におけるオートホワイトバランス (AWB) モード
CaptureRequest.CONTROL_AWB_MODE を介して設定します。
| モード (CONTROL_AWB_MODE_*) | 効果 | ユースケース |
|---|---|---|
OFF | 手動ホワイトバランスのみ。COLOR_CORRECTION_GAINS などを明示的に使用。 | プロモード、RAW 現像 |
AUTO | デフォルト。光源検出を継続的に実行。 | 一般的な撮影 |
INCANDESCENT | 約 2800K。温かみのある白熱灯のオレンジを打ち消すための強い青ゲイン。 | 屋内の電球下 |
DAYLIGHT | 約 5500K。標準的な正午の太陽光プロファイル。 | 晴天の屋外 |
SHADE | 約 7500K。日陰の強い青みを抑えるための赤ゲイン。 | 屋外の日陰 |
まずサポートされているモードを確認する: すべてのデバイスが 9 つのプリセットすべてをサポートしているわけではありません。
val availableAwbModes = characteristics.get(
CameraCharacteristics.CONTROL_AWB_AVAILABLE_MODES
) ?: intArrayOf()
Log.d("AWB", "使用可能なモード: ${availableAwbModes.toList()}")
ホワイトバランス補正の仕組み:その裏側
AWB はセンサーの RGB から表示用の sRGB へ変換するために、2 つの色変換を適用します。
ステップ 1:チャンネルゲイン (白点補正)
まず、各カラーチャンネルにゲイン(増幅率)を掛け、グレーのターゲットで R, G, B が等しくなるようにします。
Camera2 では、これは CaptureRequest.COLOR_CORRECTION_GAINS として公開されています。これは [R, Geven, B, Godd] の順序で並んだ 4 つの浮動小数点配列です。
// [ R ゲイン, G-even ゲイン, B ゲイン, G-odd ゲイン ]
val warmGains = floatArrayOf(1.0f, 1.2f, 0.8f, 1.2f) // 暖色系:赤を強調し、青を抑える
ステップ 2:3×3 色変換行列 (ガマットマッピング)
チャンネルゲインは白点を補正するだけです。しかし、センサーによって色の特性が異なるため、標準的な色空間(sRGB や DCI-P3 など)にマッピングするために 3×3 色補正行列 (CCM) が使用されます。
Camera2 では COLOR_CORRECTION_TRANSFORM を介して、Rational[9] 配列(行優先)で設定します。
実装例:完全な手動 AWB — 夕暮れ用の暖色ゲイン
究極のクリエイティブな制御のために、AWB を完全に無効にして独自のゲインを書き込みます。
fun applyManualGains(gains: FloatArray) {
val request = captureSession.device.createCaptureRequest(
CameraDevice.TEMPLATE_PREVIEW
).apply {
addTarget(previewSurface)
// 1) AWB を完全に無効にする
set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_OFF)
// 2) 4 つのチャンネルゲインを適用する
set(CaptureRequest.COLOR_CORRECTION_GAINS, gains)
// 3) モードを設定(ゲインのみ手動、行列は HAL に任せる場合)
set(CaptureRequest.COLOR_CORRECTION_MODE,
CameraMetadata.COLOR_CORRECTION_MODE_FAST)
}
captureSession.setRepeatingRequest(request.build(), null, null)
}
まとめ
- 色温度 (K): 低いとオレンジ、高いと青。AWB はこれを打ち消してニュートラルにします。
- AWB モード:
AUTOやOFFのほか、光源に合わせた各種プリセットがあります。 - マニュアル制御:
COLOR_CORRECTION_GAINSで 4 つのチャンネルの増幅率を直接指定します。 - CCM 行列: センサーの固有の色空間を標準の出力空間(sRGB など)へマッピングします。
次のステップ
露出、フォーカス、ホワイトバランスの個別の制御方法を学びました。第17章:3Aパイプラインでは、これら 3 つを組み合わせて、プロのカメラアプリがシャッターを押すたびに実行している一連のキャプチャシーケンス(3A Orchestration)を構築します。