ひとりラボ
2008年05月04日
【processing】ひとりラボ日記「pic to nes その2」
誰の為に書いてるのかよくわからないサンデープログラマー日記。
前回の続きです。
画像を指定した大きさのドットで描画する処理はできた。
指定する色数に減色することもできた。
今回はファミコンのカラーパレットを適用する処理を考える。
■ファミコンのカラーパレットの定義

ファミコンのカラーパレットは全52色。
グレースケールを含めた基本13色×輝度4段階。
カラーコードはこちらのサイトを参考に。
正確にはファミコンの色はRGBで定義されてないらしく、あくまで近似値。
もともとカラーテレビの規格が白黒テレビの互換性を持たせるために
グレースケールの輝度+色情報という定義になってるらしく、
処理を軽くするためにファミコンもこれに準拠しているそうな。
■ドットのカラーにファミコンのカラーパレットをマッピング
さて、前回の画像にファミコンカラーを適用するには
ドット一つひとつに対してこの52色のパレットから
最も近い色を選ぶという処理を行うわけだが、
調べれば調べるほどこのアルゴリズムが実に複雑で面倒臭い。
減色のアルゴリズムだけで論文一本書ける勢い。
今回は厳密性よりもなるべく処理の軽さを優先したい、ということで
単純にRGBの3次元空間に点としてマッピングした
色同士の距離を比較することにする。
√{ (ドットのR−カラーパレットのR)^2
+(ドットのG−カラーパレットのG)^2
+(ドットのB−カラーパレットのB)^2 }
元のドットの色に対して
上の式の値が一番小さくなるカラーパレットの色を適用すれば良い、と。
つまりドットあたり52回この式を実行するわけでかなり力技。
※元の色とマッピングする色を比較するプログラムを用意したので
興味がある人は確認してみてください(要Javaプラグイン)。
このBefore-Afterを確認してみると
実際の知覚とは差がある時も結構あることが分かる。
彩度や明度の差より色相の差の方が大きく見えるだろうしね。
この辺を突き詰めていくと一つの学問になってしまうと感じたのが
最初に言った「論文一本書ける」と言った理由。
■同時発色数の制限
ファミコンの同時発色数は(色々細かいルールがあるけど)最大24色だ。
上の処理だけだと52色フルに使ってしまう可能性もあるわけで、
これをどのように24色に絞るか考えてみる。
調べたところ一番オーソドックスな方法は
全ドットを集計してカラーパレットから多く使われる色24種類を選ぶ。
使用頻度が少ない色はこの24色のどれか近い色に置換するという方法。
この方法なら、画像によって使う色を自動的に選べるわけだけど、
動画の1フレームごとにこの処理を行うのは結構大変と思われる
(実際試したわけではないので今後要実験)。
ふと思いついたのは、
ドットの色のbit数を一度落としてからマッピング処理を行う方法。
同時発色数は24色なので、この数字に近いRGB各3段階の27色に減色する。
やってみた結果割と良い感じなんだけども、
考えてみたらこれ、27色に対するマッピングが固定だよね。
それ以外の52-27=25色が使われないんじゃ駄目だ。
で、色々試したり悩みながら
色んな画像を変換して分析(photoshopでパレットに書き出す)してみたところ、
24bit(RGB各256段階)のまま直接マッピングしても
だいたい24色程度に収まることが判明。色相環ですら32色で収まった。
というわけで、雰囲気重視の場合なら同時発色数に関しては
あまり考えなくても良いんじゃないか、というのが現時点での結論。
■今日のまとめ
ここまでの処理をまとめる。
1.指定したサイズのドット内のピクセルの色の平均値を求め、ドットの色とする。
2.ドットの色に対してファミコンのカラーパレットから最も近い色を選び置き換える。
ソースはこちら
実際は元の色に近付けるため、若干の重み付けを行っている。
処理した画像もいくつか公開してみる。
アプリにする際にはパラメータをある程度いじれるようにしたいね。

前回の時点より鮮やかになったかな。

色相が偏ってる画像は綺麗なドット絵になる。
個人的に気に入ったので壁紙サイズも作成(画像をクリック)。


真っ黒にならなくて良かった。


FFのテーマが聴こえてくる。
空ののっぺり感はまさにファミコン。

携帯壁紙にお勧めな一枚。
これサーバ上に設置して自由にドット絵作成できるようにしたら流行らないかな?
画像出力はだいたいできたので次回の課題は動画のリアルタイム画像処理。
前回の続きです。
画像を指定した大きさのドットで描画する処理はできた。
指定する色数に減色することもできた。
今回はファミコンのカラーパレットを適用する処理を考える。
■ファミコンのカラーパレットの定義
ファミコンのカラーパレットは全52色。
グレースケールを含めた基本13色×輝度4段階。
カラーコードはこちらのサイトを参考に。
正確にはファミコンの色はRGBで定義されてないらしく、あくまで近似値。
もともとカラーテレビの規格が白黒テレビの互換性を持たせるために
グレースケールの輝度+色情報という定義になってるらしく、
処理を軽くするためにファミコンもこれに準拠しているそうな。
■ドットのカラーにファミコンのカラーパレットをマッピング
さて、前回の画像にファミコンカラーを適用するには
ドット一つひとつに対してこの52色のパレットから
最も近い色を選ぶという処理を行うわけだが、
調べれば調べるほどこのアルゴリズムが実に複雑で面倒臭い。
減色のアルゴリズムだけで論文一本書ける勢い。
今回は厳密性よりもなるべく処理の軽さを優先したい、ということで
単純にRGBの3次元空間に点としてマッピングした
色同士の距離を比較することにする。
√{ (ドットのR−カラーパレットのR)^2
+(ドットのG−カラーパレットのG)^2
+(ドットのB−カラーパレットのB)^2 }
元のドットの色に対して
上の式の値が一番小さくなるカラーパレットの色を適用すれば良い、と。
つまりドットあたり52回この式を実行するわけでかなり力技。
※元の色とマッピングする色を比較するプログラムを用意したので
興味がある人は確認してみてください(要Javaプラグイン)。
このBefore-Afterを確認してみると
実際の知覚とは差がある時も結構あることが分かる。
彩度や明度の差より色相の差の方が大きく見えるだろうしね。
この辺を突き詰めていくと一つの学問になってしまうと感じたのが
最初に言った「論文一本書ける」と言った理由。
■同時発色数の制限
ファミコンの同時発色数は(色々細かいルールがあるけど)最大24色だ。
上の処理だけだと52色フルに使ってしまう可能性もあるわけで、
これをどのように24色に絞るか考えてみる。
調べたところ一番オーソドックスな方法は
全ドットを集計してカラーパレットから多く使われる色24種類を選ぶ。
使用頻度が少ない色はこの24色のどれか近い色に置換するという方法。
この方法なら、画像によって使う色を自動的に選べるわけだけど、
動画の1フレームごとにこの処理を行うのは結構大変と思われる
(実際試したわけではないので今後要実験)。
ふと思いついたのは、
ドットの色のbit数を一度落としてからマッピング処理を行う方法。
同時発色数は24色なので、この数字に近いRGB各3段階の27色に減色する。
やってみた結果割と良い感じなんだけども、
考えてみたらこれ、27色に対するマッピングが固定だよね。
それ以外の52-27=25色が使われないんじゃ駄目だ。
で、色々試したり悩みながら
色んな画像を変換して分析(photoshopでパレットに書き出す)してみたところ、
24bit(RGB各256段階)のまま直接マッピングしても
だいたい24色程度に収まることが判明。色相環ですら32色で収まった。
というわけで、雰囲気重視の場合なら同時発色数に関しては
あまり考えなくても良いんじゃないか、というのが現時点での結論。
■今日のまとめ
ここまでの処理をまとめる。
1.指定したサイズのドット内のピクセルの色の平均値を求め、ドットの色とする。
2.ドットの色に対してファミコンのカラーパレットから最も近い色を選び置き換える。
ソースはこちら
実際は元の色に近付けるため、若干の重み付けを行っている。
処理した画像もいくつか公開してみる。
アプリにする際にはパラメータをある程度いじれるようにしたいね。
前回の時点より鮮やかになったかな。
色相が偏ってる画像は綺麗なドット絵になる。
個人的に気に入ったので壁紙サイズも作成(画像をクリック)。
真っ黒にならなくて良かった。
FFのテーマが聴こえてくる。
空ののっぺり感はまさにファミコン。
携帯壁紙にお勧めな一枚。
これサーバ上に設置して自由にドット絵作成できるようにしたら流行らないかな?
画像出力はだいたいできたので次回の課題は動画のリアルタイム画像処理。
2008年05月02日
【processing】ひとりラボ日記「pic to nes その1」
切なくてニューゲーム編からの新企画(≒趣味垂れ流し)ということで
ネタアプリ制作工房「ひとりラボ」始めます。
今月初めに買った入門書をようやく読み終えたので
早速processingを使ったアプリを作ってみようと思う。
多分そんなに毎日は触ってられないので
ある程度進展があれば、という形で経過報告。
面白いものができればここで公開・配布するかもしれません。
今日から取り組む最初のテーマは
「画像をファミコン風に変換するプログラム」
主な処理としては、
1.変換する画像のpixel配列(pixelごとの色データ)を読み込む。
2.数px平方の正方形を1dotとして、dotごとに色の平均値を算出する。
3.ファミコンっぽく減色して描画。
で、作ったプログラムで変換させたのが以下の画像。
ソースはこちら(pic_to_nes.pde)。

元画像

1[dot] = 2x2[px]

1[dot] = 3x3[px]

1[dot] = 4x4[px]
ドットの粗さとしては2x2か3x3がいいかな。
色はファミコンにしては自然過ぎる印象。
どうやらファミコンは白黒透明含めた52色が用意されているらしく、
とりあえずそれに近い64色(RGBそれぞれ4段階)に設定してみたんだけど、
さらに調べたところ同時発色数は24色らしいことが判明。
そこでRGBそれぞれ3段階の27色にして出力してみた。

1[dot] = 2x2[px] 27色
のっぺり感はファミコンに近付いたけど、色のセレクトがいまいちだ。
というわけで次の課題は、
・ファミコンのカラーパレットを手に入れる(知ってる人いたら教えてください)。
・52色中最大24色までしか使わないという処理を加える。
連休中にはwebカメラの動画をリアルタイム変換するところまで行きたいぜ。
ネタアプリ制作工房「ひとりラボ」始めます。
今月初めに買った入門書をようやく読み終えたので
早速processingを使ったアプリを作ってみようと思う。
多分そんなに毎日は触ってられないので
ある程度進展があれば、という形で経過報告。
面白いものができればここで公開・配布するかもしれません。
今日から取り組む最初のテーマは
「画像をファミコン風に変換するプログラム」
主な処理としては、
1.変換する画像のpixel配列(pixelごとの色データ)を読み込む。
2.数px平方の正方形を1dotとして、dotごとに色の平均値を算出する。
3.ファミコンっぽく減色して描画。
で、作ったプログラムで変換させたのが以下の画像。
ソースはこちら(pic_to_nes.pde)。
元画像
1[dot] = 2x2[px]
1[dot] = 3x3[px]
1[dot] = 4x4[px]
ドットの粗さとしては2x2か3x3がいいかな。
色はファミコンにしては自然過ぎる印象。
どうやらファミコンは白黒透明含めた52色が用意されているらしく、
とりあえずそれに近い64色(RGBそれぞれ4段階)に設定してみたんだけど、
さらに調べたところ同時発色数は24色らしいことが判明。
そこでRGBそれぞれ3段階の27色にして出力してみた。
1[dot] = 2x2[px] 27色
のっぺり感はファミコンに近付いたけど、色のセレクトがいまいちだ。
というわけで次の課題は、
・ファミコンのカラーパレットを手に入れる(知ってる人いたら教えてください)。
・52色中最大24色までしか使わないという処理を加える。
連休中にはwebカメラの動画をリアルタイム変換するところまで行きたいぜ。