« 誤差拡散法 | トップページ | 画像の拡大・縮小 »

24bit → 8bit 減色


リンク
画像の変換(目次ページ)
ディザ関連
パターン・ディザ
誤差拡散法
・24bit→8bit減色

24bit の画像を 8bit (256 color) にする方法について、です。

《元データ (24bit RGB)》
source data (24 bit color)

この絵の色分布(ヒストグラム)を調べると下記のようになります。
白っぽい背景の面積が大きいので、その部分にピークが出ます。

色の分布を3次元表示すると下記のようになります。
(横:Green,縦:Red,奥行:Blue)
分布がある領域に固まっている事がわかります。


別の画像のヒストグラムを調べると下記のようになります。
《元データ (24bit RGB)》
source data (24 bit color)



このように、通常の絵のヒストグラムは、ある領域に分布が集まったもの、
あるいは、幾つかの分布領域が組み合わさったものになります。


さて、24bit の画像を 8bit (256色) に減色する事について考えましょう。

『24bit → 8bit 減色』というのは、
最近ではほとんど必要性が無くなってしまったのかもしれません。
昔は・・・
ディスプレイ(モニター)が 256 色にしか対応していなかったりで、
より奇麗に見せるための技術として、
あるいは、インターネット回線が細いために、
Web ページを少しでも軽くする、という目的で有用な技術でした。


まずは、例によって、最も簡単なアイデアからです。
最も簡単な減色方法の考え方は、
R,G,B それぞれを等分割する。
というものです。
下記は、「RとGを7分割、Bを5分割」したものです。
R = { 0, 43, 85, 128, 170, 213, 255 };
G = { 0, 43, 85, 128, 170, 213, 255 };
B = { 0, 63, 127, 191, 255 };
の組み合わせでパレットを作成し、
元絵のそれぞれのピクセル値を一番近いパレット値に置き換えたものです。

《固定パレット》
(24bit→8bit (245 color))》
reduced color into fixed palette by threshold

《固定パレット》
(24bit→8bit (245 color))》
reduced color into fixed palette by threshold

芸術的な感じに仕上がりました。
ですが、元々の画像からは遠くなっています。

元絵に近づけるために『誤差拡散法』を利用できないでしょうか?

元絵のピクセル値(R:G:B) と選択したパレット値 (R':G':B')の差分を
「誤差拡散法」で拡散する。
つまり、
  ⊿R = R - R'
  ⊿G = G - G'
  ⊿B = B - B'
の (⊿R,⊿G,⊿B)を 7/16, 3/16, 5/16, 1/16 の比率で誤差拡散。


このやり方で作ったのが下記です。
「誤差拡散なし」よりも「誤差拡散あり」の方が奇麗だと思います。
(あくまで、個人的な感想ですが。)

《固定パレット》
(24bit→8bit (245 color))
+誤差拡散(Floyd-Steinberg)》
reduced color into fixed palette with error diffusion

《固定パレット》
(24bit→8bit (245 color))
+誤差拡散(Floyd-Steinberg)》
reduced color into fixed palette with error diffusion

誤差拡散のお陰で、質感は上がりましたが、
やはり「誤差拡散」特有の点々があるために、表面がザラザラした感じがします。
(言い方が抽象的だなぁ)

もう少しリアルな表面のスベスベ感、フワフワ感を出せないでしょうか?

考えてみると、固定パレットには無駄なエントリ(=パレット要素)が多すぎます。
たとえば、金魚の絵では、緑色のパレットは要りません。
その代わりに、赤と黄色の中間色を追加した方が奇麗になりそうです。
そうやってパレットを最適化したものが下記です。
《最適化パレット》
(24bit→8bit)
+誤差拡散(Floyd-Steinberg)》
reduced color into adaptive palette(generate by median cut) with error diffusion

《最適化パレット》
(24bit→8bit)
+誤差拡散(Floyd-Steinberg)》
reduced color into adaptive palette(generate by median cut) with error diffusion


では、『最適化パレットの作り方』です。

「メディアン・カット(Median Cut,中央値分割)」という方法を用います。

それぞれの画像でヒストグラムを求めると下記のようになったとします。
(実際には R-G-B の3次元です。)


メディアン・カットは、まずピクセル領域を絞り込む事から始めます。
これがコツっぽいです。

次に、領域に含まれるピクセル数が半々になるように分割します。
分割したら、それぞれの領域を絞り込みます。

これを何度か繰り返します。

「何度か」という表現が曖昧ですが、
終了条件としては、
・領域の大きさがある一定値よりも小さくなったらそれ以上分割しない。
・領域に含まれるピクセル数が一定値よりも少なくなったら分割しない。
というやり方でよさそうです。
分割が終わったら、領域(=立方体、Cube )の端点をパレットに追加します。

この時、外側の点(上図の赤い)はパレット登録した方が奇麗になります。
密集点(上図の緑の)はどれか1つを登録します。

最後に画像を比較しておきましょう。(見た目の比較)
《元データ (24bit RGB)》
source data (24 bit color)

《固定パレット》
(24bit→8bit (245 color))》
reduced color into fixed palette by threshold

《固定パレット》
(24bit→8bit (245 color))
+誤差拡散(Floyd-Steinberg)》
reduced color into fixed palette with error diffusion

《最適化パレット》
(24bit→8bit)
+誤差拡散(Floyd-Steinberg)》
reduced color into adaptive palette(generate by median cut) with error diffusion

注)実は、このメディアン・カット、
RGB ではなく、YCbCr に変換してからカットを行っています。
(「その方が良さそうな気がする」というだけの理由です。)
しかし、如何せん、プログラマが私ですから、パレットの選択がまだまだ甘い。
そんな訳で、ちゃんとした「最適化パレット」というよりは、
「最適化パレット(なんちゃって)」というのが本当のところです。

ちなみに、上記《固定パレット》で用いたパレットを表したものが下記です。

上記、金魚の《最適化パレット》で用いたパレットは下記です。

《元データ (24bit RGB)》
source data (24 bit color)

《固定パレット》
(24bit→8bit (245 color))》
reduced color into fixed palette by threshold

《固定パレット》
(24bit→8bit (245 color))
+誤差拡散(Floyd-Steinberg)》
reduced color into fixed palette with error diffusion

《最適化パレット》
(24bit→8bit)
+誤差拡散(Floyd-Steinberg)》
reduced color into adaptive palette(generate by median cut) with error diffusion

上記、フルーツ盛り合わせの《最適化パレット》のパレットは下記です。

|

« 誤差拡散法 | トップページ | 画像の拡大・縮小 »

画像フォーマット」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック

この記事のトラックバックURL:
http://app.f.cocolog-nifty.com/t/trackback/167561/29348758

この記事へのトラックバック一覧です: 24bit → 8bit 減色:

« 誤差拡散法 | トップページ | 画像の拡大・縮小 »