2013-09-24

ガンマ補正と簡単な高速化

ガンマ2.2のディスプレイの場合、入力に対する出力は下図のようになる。













このとき、0.4の入力を与えると出力は約0.133、0.8の入力であれば約0.612の出力になる。
ディスプレイやビデオカードで(出力) eq (入力)となるように補正するといいのだが、歴史的経緯で行っていなく、この状態で利用していると自然とデータにガンマ補正を掛けてしまう。
下図のように、x2.2のディスプレイであれば、x1.0にするためにx1.0/2.2となる。













ガンマ補正が掛かっているデータは非線形であるため、画像処理を行うには非常に都合が悪い。
そこで、処理前に2.2乗してガンマ補正を解除する。
処理後は(1.0/2.2)乗してガンマ補正する。
公開を停止した富士通のColorDoctorは異様に重く、それがCoffretを作成するきっかけとなった。
前述したガンマ補正解除とガンマ補正に用いる冪乗(pow)は非常に重い処理で、加算の数百倍から千倍程度の時間が掛かるくらいだし、一つのドットで6回使う。
高速化するにはpowを無くすのが容易な上に最も効果的だ。
入力値は0..255の整数、ガンマ値は定数なので、事前にテーブルを作って引けばいい、初歩中の初歩。
これで『255で割って0~1にする』、『r,g,bをそれぞれ2.2乗する』をLUT引き一発で済ませられる。
たったこれだけで、処理時間は1/3程度になる。

(1.0/2.2)乗の部分はLUTを二分検索して添え字を求める。
その副作用で『0未満なら0にする』、『整数型にする』、『255より大きいなら255にする』も同時に済む。
これも行うと、処理時間は1/10程度になる。

#SIMDを使っての最適化を考えると、64[bit]環境とSSE4.1くらいは欲しくなる

0 件のコメント:

コメントを投稿