単純減色(ポスタライズ?)試してみた、WPFとC#
今回は
WPF、普通の写真画像を8色に減色 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/15342796.html
この記事の続き
8色に減色だったのを27色,64,512、…ってしてみた
8色のときはRGBそれぞれの色の強さ0か255を2階調(分割)して0か255に分けて
その組み合わせは
R,G,B
黒 (0, 0, 0)
赤 (255,0, 0)
緑 (0, 255, 0)
青 (0, 0, 255)
黄色 (255,255, 0)
水色 (0, 255,255)
赤紫 (255,0, 255)
白 (255,255, 255)
の8色だった
今回はこの階調(分割)数を増やして
3階調なら0,127,255の3つの強さ
R,G,B
黒 (0, 0, 0)
赤黒 (127,0, 0)
赤 (255,0, 0)
0と255の間に中間の127が入る
RGBそれぞれで3階調で組み合わせが合計27色
4階調なら0,85,170,255で64色、5階調で512色…
元の画像は普通のjpeg画像なので
1677万色
RGB各2階調の全8色は前回と同じ
8色と言っても元の画像に赤、緑、黄色、赤紫はないから
実質は白、黒、青、水色の4色
ファミコンかな
3階調27色、これもファミコンっぽい
8色のほうがいいかなあ
4階調64色、メガドライブな感じ、いやもうちょっときれいだったかw
3階調よりはいいけど、まだ違う
5階調125色、これもメガドライブだなあ
6階調216色
PCエンジン…はもっときれいだったかな
8階調512色、スーパーファミコン
いいね
16階調4096色
このへんまで来ると元の画像と差がなくなってくる
128階調で約210万色
元の画像と見分けがつかない
256階調、1677万色は元の画像と同じ色数なので
全く同じはず
RGBそれぞれを2階調
閾値128で0か255を分けているのが水色のところ
0から255を0か255の2階調に変換する(分ける)から閾値はその中間の128にしている
0 になるのは0から127の 範囲は128
255 になるのは128から255の 範囲は128
ちょうど2等分できている
3階調の場合
閾値の85.3と171は256/3=85.333333…
これが一つ分の区切り位置になるから
1つ目の区切り位置は85.3*1=85.3
2つめの区切り位置は85.3*2=170.6
なんか微妙に画像と違うけど修正めんどくさい
0 になるのは0から85 範囲は86
127 になるのは86から170 範囲は85
255 になるのは171から255 範囲は85
これでだいたい3等分できている
4階調
こんなふうに階調ごとに書くのはめんどくさいので
色の値(強さ)と階調数を渡して変換した色の値(強さ)を返す
frequency=256/3=85.3333…
if(100<85.3*1)=false
if(100<85.3*2)=True
v=255/(3-1)=127.5
return 127.5*(2-1)=127.5をbyte型にキャストで127
127を返す
階調数5で値200を渡すと
frequency=256/5=51.2
if(200<51.2*1)=false
if(200<51.2*2)=false
if(200<51.2*3)=false
if(200<51.2*4)=True
v=255/(5-1)=63.75
return 63.75*(4-1)=191.25をbyte型にキャストで191
191を返す
256を渡された階調数で割っているのは
閾値の一区切りの値
を求めるためなのはさっきの通りで
もう一つの255を階調数-1で割っているのは
変換後の値のための一区切りの値
3階調
255/(3-1)=127.5
127.5*0=0
127.5*1=127.5
127.5*2=255
これで変換後の3階調の値になる
こんな感じになるけど今見たらIFのところの不等号は<=のほうがいいかなあ
これを使って
これで階調ごとに書かなくて済むようになった!
これでできたんだけどもっと速く!
ポスタリゼーション(階調変更)こちらで紹介されている方法
http://www.sm.rim.or.jp/~shishido/post.html
僕のアタマでは全部は理解できなかったので部分的に参考にして
これは最初に変換用の一覧表を作っておいて、あとはそれを使って判定するだけ
3階調なら0から
0 になるのは0から85
127 になるのは86から170
255 になるのは171から255
逆に言うと
0から85は 0
86から170は 127
171から255は 255
なので配列を使って一覧表を作ると
indexをもとの値
valueを変換後の値にして
要素数は0から255なので256個
って見たほうが早い
converterってのがそれ、中を見ると
いっぱい入っている
85までは0で86から127が入っていて
次の区切りは170…
170まで127
それ以降は255が入っている
こうして作った一覧表を使って
indexはp+2
今のpは0なのでpixels[2]を変換する
これを一覧表のconverterのindexにして中の値を
入れれば変換完了になる
converter[34]の値0がpixels[2]に入って
変換完了!
他の値も同じように一覧表を使って変換
75は0へ
155は127に変換
いやーよく思いつくなあ、スゴイ
ピクセル数、階調数ともに大きくなるほど差が大きくなって
2048x1536ピクセルの画像を変換する時
最初の方式だと
2階調 0.5秒くらい
8階調 1秒弱
16階調 1.5秒くらい
128階調 5秒くらい
256階調 10秒
だったのが
一覧表方式だと
2階調 一瞬
256階調 一瞬!
同じ結果を得るにしても方法に依っては、こんなに差が出るのが面白いねえ
ポスタライズって言うみたいねえ、減色してベッタリしたような画像にするの
単純減色って呼んでた
グレースケールでも128階調は元の画像と見分けつかないなあ
32,48はわかるけど64階調は注意して見ないとわかんない
コード
gogowaten/20180226forMyBlogわてんはGitHubがわからん
https://github.com/gogowaten/20180226forMyBlog
アプリダウンロード先
ここの20180224_.zip
つづきは2日後
単純減色(ポスタライズ)にオーダード(パターン)ディザリング、WPFとC# ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/15391499.html
関連記事
1ヶ月前
WPF、普通の写真画像を8色に減色 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/15342796.html
2018/03/02は4日後
単純減色と誤差拡散とディザリング ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/15394008.html