RGB 値の正規化: 255 で割る vs 256 で割る
画像処理のために 8 ビット RGB 整数を浮動小数点値に変換する際、開発者は 255 で割るか 256 で割るかで正規化すべきか議論することが多い。ほとんどのアプリケーション—特に外部ソースからの画像を処理する場合—255 で割ることが正しい選択である。なぜなら、整数 0 が正確に 0.0(黒)に、整数 255 が正確に 1.0(白)にマップされることを保証するからだ。
標準的なアプローチ: 255 で割る
標準的な正規化式は整数範囲 $[0, 255]$ を浮動小数点範囲 $[0.0, 1.0]$ にマップする。
実装
# Integer to Float
pixels = img / 255.0
# Float to Integer
output = np.trunc(result * 255 + 0.5).clip(0, 255).astype(np.uint8)
利点とトレードオフ
- 絶対的な極端: この方法だけが、純粋な黒 (0) と純粋な白 (255) をそれぞれ 0.0 と 1.0 で表現できる。$f(0)=0$ という代数的性質に依存するアルゴリズムや、黒ピクセルを検出する処理にとって重要である。
- 業界互換性: これは GPU が UNORM(符号なし正規化)カラーを扱う方法でもある。標準画像ファイルを読み込む際に他の手法を使うと、ほとんどの場合 255 スケールで量子化された画像なのでエラーが生じやすい。
- 「ハーフビン」問題: 技術的な欠点として、浮動小数点から整数へ戻すとき、極端なビン(0 と 255)の幅が内部ビンの半分になる。$[0, 1]$ の一様乱数を生成した場合、0 と 255 の出現頻度は他の整数の半分になる。
代替アプローチ: 256 で割る
一部の開発者は 0.5 のバイアスを加えて 256 で割ることを好む。これは各整数をスケール上の点ではなくビンの中心として扱う方法だ。
実装
# Integer to Float
pixels = (img + 0.5) / 256.0
# Float to Integer
output = np.trunc(result * 256).clip(0, 255).astype(np.uint8)
利点とトレードオフ
- 均一なビン幅: このアプローチは極端部の「ハーフビン」問題を解消し、エッジケース処理なしでノイズを加える必要がある特定のディザリングに適している。
- 理論的精度: 保存と読み込みの両方を自分で管理できる閉じたシステムでは、256 で割る方が平均絶対再構成誤差が若干低くなる($1/1024$ 対 $1/1020$)。
- 絶対ゼロの喪失: 主な欠点は整数 0 が 0.0 ではなく $0.5/256 \approx 0.00195$ にマップされることだ。これにより処理ロジックが 8 ビット入力深度に結びつき、0.0 を黒の信頼できる指標として使えなくなる。
量子化理論: ミッドライザー vs ミッドトレッド
この 2 つの手法は、異なるタイプの一様スカラー量子化器を表す。
- ミッドライザー(標準/255): ゼロをゼロにマップする。符号なし 8 ビットデータの文脈では、$L=255$ の修正ミッドライザーアプローチになる。
- ミッドトレッド(代替/256): ゼロを 2 つの整数の中間にマップする。これは $L=256$ のミッドトレッド量子化器である。
専門家の見解と反論
コミュニティの議論は、単なる除算以上の実用的な考慮点を浮き彫りにしている。
- ハードウェア制約: マイコンで VGA 信号を生成するような特定ハードウェア環境では、これらの値の精度が重要になる。色チャンネル間のビット深度が合わないと、純粋なグレーが欠け、グラデーションに色かぶりが見える。
- ディザリング: グレースケールグラデーションのバンディングを防ぐため、専門家は 256 除算バイアスに頼るのではなく、浮動小数点から整数への変換時に三角形ディザを加えることを推奨する。
- 色空間への意識: 多くは除算子の選択は転送関数の方が重要だと主張する。ほとんどの 8 ビット画像はリニア RGB ではなく sRGB(非線形)を使用しているため、正規化の数学的精度はガンマ補正プロセスに埋もれがちである。
"他人から提供された画像を処理するのであれば、RGB 値は 255 で正規化すべきです。非正確な浮動小数点値や、抽象的な再構成誤差の増大感は代替手法を選ぶ正当な理由にはなりません。"
まとめ表
| 機能 | 255 で割る | 256 で割る |
|---|---|---|
| 0 が 0.0 にマップ | はい | いいえ |
| 255 が 1.0 にマップ | はい | いいえ |
| ビン幅 | 極端は半幅 | すべてのビンが均一 |
| 標準 | GPU / 業界標準 | 特殊 / 理論的 |
| 最適な使用ケース | 一般的な画像処理 | 閉ループ高精度システム |