まず簡略化の前に前回言い忘れてたことがあります。
行列の計算はdouble型の変数で行なっていましたってことです。
普通HSP以外では小数入りの計算は整数の計算と比べて劇的に遅く、セピア変換の計算などは整数型の変数を全部1024倍して計算するのが主らしいのですが、私の扱っているHSPは小数の計算も整数と同じくらいの速さなので正直に小数入り変数double型で計算をしている構造になっています。
ところで出力は整数型でいいのに何で小数入り型にしたり1024倍したりするのかは分かりますよね・・?小数切捨てで誤差ができるのを防ぐためです。
ではそろそろ本題のアルゴリズム簡略化に着手しましょう!
まず、どう考えても無駄なのはRGB→YUVの作業のUを決める計算とVを決める計算です。
どうせ2、3行後で定数を代入されるのですから・・・・
で、いっそのことUとVの変数を削除してしまえという結論にたどり着きます。
するとループ内の計算は以下のようになります。
gsel 1
pget cnt,a:r=ginfo_r:g=ginfo_g:b=ginfo_b ; RGB値を取得し代入
y=0.299*r+0.587*g+0.114*b ; 行列の計算1
r=1.0*y+1.402*14.336 ; 逆行列の計算1
g=1.0*y+0.334*23.296-0.714*14.336 ; 逆行列の計算2
b=1.0*y-1.772*23.296 ; 逆行列の計算3
gsel 2
color r,g,b
pset cnt,a
あとは掛け算と足し算をあらかじめ計算し終えておけば
gsel 1
pget cnt,a:r=ginfo_r:g=ginfo_g:b=ginfo_b ; RGB値を取得し代入
y=0.299*r+0.587*g+0.114*b ; 行列の計算1
r=20.01+y ; 逆行列の計算1
g=-2.46+y ; 逆行列の計算2
b=-41.28+y ; 逆行列の計算3
gsel 2
color r,g,b
pset cnt,a
とこうなり
もう r g bの変数も必要ないと思うようになり
gsel 1
pget cnt,a
y=0.299*ginfo_r+0.587*ginfo_g+0.114*ginfo_b
gsel 2
color 20.01+y,-2.46+y,-41.28+y
pset cnt,a
ここまで簡略化することができました!!
最初r g b y u vの6つだったのがもうyしか変数が残っていません!!
さてここで、プログラムをよく見てほしいのですがこれはグレースケール変換プログラムにすごい似ているのです。
グレースケール変換プログラムはこれです。(ループ内のみ)
gsel 1
pget cnt,a
y=0.299*ginfo_r+0.587*ginfo_g+0.114*ginfo_b
gsel 2
color y,y,y
pset cnt,a
見てください。color の指定以外全部一緒です!
つまりセピア画像はグレースケール画像に色をちょっと加算&減算しただけのもので、セピア限定のなにか特別な処理方法で算出した色ではなかったと言うことです!!
見た目は違えどカレーとシチューみたいに途中まで作り方が同じだったってことに自分で発見したとき驚きでした!! (例えに無理あるなw)
「セピア変換プログラム」でググってでてきたページの中に、誰もグレースケールにちょっと色を加えるだけだよ、と書いてなかったのでなんか自分が一番最初に発見した、エライ人みたいな気分になってます(笑)
ところでまた話はそれますがグレースケールの計算でなぜ(R+G+B)/3じゃないのか
って思うかもしれません。
私も最初そう思いました。
一応それでも正解なのだそうですが、人間の目では緑の明るさがより強く感じられるみたいなので、
そこを考慮すると全て3分の1すりゃいいってわけにはいかんみたいなんです。
なので人間の目に対してよりリアルなグレースケール画像を作りたかったら↑の計算式を
コンピューターに対してよりリアルなグレースケールなら全部3分の1って計算でっでいうことでおkみたいです