RandomThoughts

RandomThoughts

ガンマ補正

Contents:
  1. a0とa0*sの値の違い
    1. 教科書でのガンマ、逆ガンマ補正
    2. 別計算(webでよくある)パラメータでのガンマ補正
  2. sRGBのlinearとnon linearの具体的な値のテーブル

【書籍】PrinciplesOfDigitalImageProcessingの話をベースにいろいろ書き足していく。(以下では「教科書」といったらこの本)

ガンマ補正はどちらが補正されていてどれが元の値かよくわからなくなるので以下にメモを書いておく。

カメラなどのセンサーの受け取る強度と人の目の知覚は異なる。 そこで画像データなどはセンサーの強度ではなく、それをガンマ補正した値を保存している。 つまり画像ファイルなどのRGB値 = ガンマ補正されたsRGB値 = non linearなsRGB値。

これは教科書p85のTable 4.1のsRGBのパラメータでガンマ補正されている。

画像処理をする場合はこれをlinearな強度に戻して(=逆ガンマ補正)、処理をして、結果をガンマ補正する必要がある。

a0とa0*sの値の違い

a0の値として教科書では0.00304が使われているが、sRGB - Wikipediaなどでは場合分けを 0.0031308で行っている。 どういう事だろう?

sRGB色空間と国際標準化.pdfの付録にこの違いについて書かれている。計算の丸め誤差らしい。

a0, a0*sは、以下の2つの流儀があり、どちらも使われているらしい。

  • 教科書: (0.00304, 0.03929)
  • 別計算: (0.0031308, 0.04045)

別計算の方がIEC 61966-2-1には書かれているらしく、web上では別計算の方が多い気がする。

以下、これらのパラメータを元にガンマ補正と逆ガンマ補正の式を以下に書いておく。 これは教科書の式4.33、4.35にテーブル4.1の値や上記のパラメータを入れたもの。

疑似コードは適当にベクトル演算されるとする(シェーダーみたいな感じに)。

教科書でのガンマ、逆ガンマ補正

逆ガンマ補正(画像ファイルから線形に戻す)

if(rgb <= 0.03929) { rgb/12.9231  } else {  ((rgb+0.055)/1.055)^2.4 }

ガンマ補正(最後に画像ファイルに戻す時)

if(rgb <= 0.00304) {  rgb*12.9231 } else { 1.055*rgb^(1/2.4) - 0.055 }

1/2.4は0.417の近似値も使われる。

別計算(webでよくある)パラメータでのガンマ補正

逆ガンマ補正(画像ファイルから線形に戻す)

if(rgb <= 0.04045) { rgb/12.9231  } else {  ((rgb+0.055)/1.055)^2.4 }

ガンマ補正(最後に画像ファイルに戻す時)

if(rgb <= 0.0031308) {  rgb*12.9231 } else { 1.055*rgb^(1.0/2.4) - 0.055 }

sRGBのlinearとnon linearの具体的な値のテーブル

【書籍】PrinciplesOfDigitalImageProcessingの2冊目、Core Algorithmの6.3.4 p 110のTable 6.5に、linearとnon linearの50%グレーなどの時の値がある。検算に良さそうなのでメモしておく。