2009年8月15日土曜日

画像処理 #21 グレースケール化

2値化はよく行いますが,カラー画像からグレースケール画像に変換するという事をやっていなかったので紹介.

以下では,
Y:グレースケール値
R:Redの値
G:Greenの値
B:Blueの値

・単純平均法(simple mean method)
Y = (R+G+B)/3

真っ先に思いつくのがこの方法な気がします.

・中間値法(middle value)
Y = (min+max)/2
min = min(R, G, B)
max = max(R, G, B)

・Gチャンネル法
Y = G

R,G,Bの内,人間の心理物理量はGが7割程度を占める為,そのまんまGを当てはめてしまおうというものです.

・NTSC係数による加重平均法(NTSC Coef. method)
Y = 0.298912*R + 0.586611*G + 0.114478*B

NTSC:National Television System Committeeは,
アナログテレビジョン放送標準方式の規格を意味します.

・HDTV係数による加重平均と補正法(ITU Coef. method)
X = 2.2
R = (R^X) * 0.222015
G = (G^X) * 0.706655
B = (B^X) * 0.071330
Y = (R+G+B) ^ (1/X)

HDTV:High Definition Televisionは,
高精細度テレビジョン放送のことを意味します.

では,実際の例を示します.





Fig.1 sample





Fig.2 simple mean method





Fig.3 middle value





Fig.4 G channel method





Fig.5 NTSC Coef. method





Fig.6 ITU Coef. method

NTSC(Fig.5),HDTV(Fig.6)がいいセンいってます.middle value(Fig.3)は,(色相を変化させた方を見ると)黄色も青も一緒の明るさになっていて,再現度は低いといえます.simple mean method(Fig.2)もあまり良くないです.G channel(Fig.4)はパッと見良さそうに見えますが,それは気のせいというものです.
というわけで,グレースケール化する際には(他にも)色々と手法がある(らしい)ので注意しましょう.




おまけ:グレースケール化のガイドライン

面接官「特技はグレースケール化とありますが?」
学生 「はい。グレースケール化です。」
面接官「グレースケール化とは何のことですか?」
学生 「画像処理です。」
面接官「え、画像処理?」
学生 「はい。画像処理です。カラー画像をグレースケール画像にする事が出来ます。」
面接官「・・・で、そのグレースケール化は当社において働くうえで何のメリットがあるとお考えですか?」
学生 「はい。カラー画像をグレースケール化する際困りません。」
面接官「いや、当社にはグレースケール化をしようとする輩はいません。」
学生 「でも、グレースケール化楽しいですよ。」
面接官「いや、楽しいとかそういう問題じゃなくてですね・・・」
学生 「Gチャンネル法とかあるんですよ。」
面接官「ふざけないでください。それにGチャンネル法って何ですか。だいたい・・・」
学生 「Gチャンネル法です。“爺ちゃん寝る”が語源でして、R、G、Bの内、心理物理量7割を占めるGチャンネルをそのまま・・・」
面接官「聞いてません。帰って下さい。」
学生 「あれあれ?怒らせていいんですか?使いますよ。グレースケール化。」
面接官「いいですよ。使って下さい。グレースケール化とやらを。それで満足したら帰って下さい。」
学生 「運がよかったな。今日はカラー画像がないみたいだ。」
面接官「帰れよ。」

二番煎じ.

2009年8月14日金曜日

専門書を読む #11

集合・位相入門
~p60

やっと集合の濃度に入ります.

専門書を読む #10

集合・位相入門

~p55

2009年8月12日水曜日

知的遊戯

久しぶりにマトモなものを制作したので紹介.

「知的遊戯」
要はよくあるパズルゲームです.持っていた(実際に素手で遊ぶ)物を移植しました.
今回のコンセプトは「中国のパチモノっぽいゲーム」.


Fig.1

こんな感じ.


Fig.2

クリアすると上の画面になります.ちなみに「恭喜恭喜!」は,おめでとうの意.「初期化」クリックでまた出来ます.

2009年8月3日月曜日

画像処理 #20 雲

皆さんは,雲を作ったことがあるでしょうか.

実際に作ってみました.

この記事は,下記の参考文献の内容を実装した後,日本語で要約したものです.

1.乱数でノイズパターンを生成


Fig.1
こんな感じで4つ作ります.赤枠は単に区切るためのものです.これらをそれぞれMap1,Map2,Map3,Map4とします.

2.平均化
Map1,Map2,Map3,Map4をそれぞれ平均化します.
平均化の際,上下左右は繋がっているものとしましょう.


Fig.2

3.サンプリング
以下のようにして,Map1,2,3,4を256x256の大きさにします.
Map1:8倍に拡大.
Map2:4倍に拡大したものを,タイル状に縦横2つずつ並べる.
Map3:2倍に拡大したものを,タイル状に縦横4つずつ並べる.
Map4:タイル状に縦横8つずつ並べる.
サンプリング時には,バイリニア補間を使いました(画像処理 第1回 補間 参照).
因みに,上で述べたように,上下左右が繋がっているものとして平均化しておかないと,この時点で不自然な不連続部分が出来てしまします.


Fig.3

4.合成
これらの画像を合成します.各ピクセルの値は,
Map=Map1+Map2/2+Map3/4+Map4/8
とします.


Fig.4

5.仕上げ

最後に仕上げです.各ピクセルについて,


CloudExpCurve(v){
c=v-CloudCover;
if(c<0)
c=0;
CloudDensity=255-CloudSharpnessc * 255;
return CloudDensity;
}


というトーンカーブを適用します.

ここで,パラメタの説明を.

CloudCover:
値域[0, 255]
総雲量を制御.値が小さい程,雲は多くなる.

CloudSharpness:
値域[0, 1]
雲のシャープさを変える.小さい値だと急激な変化で濃い雲,大きい値だと曖昧で薄い雲となる.


Fig.5

Fog.5でのパラメタは,以下の通り.
CloudCover=232
CloudSharpness=0.95

完成です.それっぽい感じの雲が出来上がりました.

参考文献
Hugo Elias.“Cloud Cover”.<http://freespace.virgin.net/hugo.elias/models/m_clouds.htm>.The good-looking textured light-sourced bouncy fun smart and stretchy page.(参照2009年8月2日)

2009年8月2日日曜日

物理 #2 衝突(2次元)

今回は,2次元の衝突です.

球A:
位置:r1=(x1, y1)T
衝突前速度:v1=(v1x, v1y)T
衝突後速度:v1'=(v1x', v1y')T
質量:m1
反発係数:e1

球B:
位置:r2=(x2, y2)T
衝突前速度:v2=(v2x, v2y)T
衝突後速度:v2'=(v2x', v2y')T
質量:m2
反発係数:e2

表記の都合上,半径:rは省略します.
また,
v=(vx, vy)T=vxe1+vye2
とします.
e1, e2はそれぞれ,正規直交基底で,
e1=(1, 0)T, e2=(0, 1)T
です.

さて,この2つの球が衝突したとしましょう.どうなるでしょうか?
1次元の場合は,簡単に考える事が出来ましたが,2次元となると一筋縄ではいきません.
以下をご覧あれ.


Fig.1 Collision

衝突した瞬間の図です.ここで,
r=r2-r1
というベクトルをとったとしましょう.そして,rに垂直(=球2つの接線)なベクトルをとります.
この2つのベクトルを正規化したものをそれぞれ,
e1'=(e1x', e1y')T
e2'=(e2x', e2y')T
と表すことにします.
この時,e1', e2'は正規直交基底となります.
この基底上で考えると,e1'では,1次元空間の単純な衝突,e2'上では,速度の変動は全く無い,という事が出来ます.

というわけで,v1, v2を先の基底で表してみましょう.

v1=w1xe1'+w1ye2'
v2=w2xe1'+w2ye2'
とします.このときwは,以下の様に計算します.

w1x=v1・e1'
w1y=v1・e2'
w2x=v2・e1'
w2y=v2・e2'

wに関して衝突後の値をw'で表します.この時,
w1y', w2y'
は,衝突前に等しいので(前述),
w1x', w2x'
を求めればよいのです.

とはいえ,これは,1次元ヴァージョンの帰結に相違無いので,

w1x'=(m1w1x+m2w2x)/(m1+m2)+e(w2x-w1x)m2/(m1+m2)
w1y'=w1y
w2x'=(m1w1x+m2w2x)/(m1+m2)+e(w1x-w2x)m1/(m1+m2)
w2y'=w2y

となります.
あとは,元の基底で表すだけです.そのためには,
v1'=w1x'e1'+w1y'e2'
に,そのまま代入すればよいので,
v1x'=w1x'e1x'+w1y'e2x'
v1y'=w1x'e1y'+w1y'e2y'
v2x'=w2x'e1x'+w2y'e2x'
v2y'=w2x'e1y'+w2y'e2y'

というわけで,求める事が出来ました.

実際にシミュレーションしてみると,当たり前の動きをするのですが,感動を覚えます.

2009年7月24日金曜日

数学 #5 迷い歩き

問題:
"歩行者"は,x=0から出発して,前(+x方向)か,後(-x方向)へ1歩ずつ進む事が出来る.
前,後,どちらへ進むかは確率的であり,P(+x)=P(-x)=0.5.
この時,"歩行者"がN歩あるいたとすると,出発点(x=0)からどれだけの距離にいる事になるか.

直感的には,どちらへ行くにも等確率だから,"x=0にいる",と考えられますが….

実験:
歩行者:8人


Fig.1 256歩


Fig.2 1024歩


Fig.3 4096歩

それぞれの画像に置いて,右端が(256, 1024, 4096)歩あるいた時の歩行者の位置で,1つ左のピクセルが,(255, 1023, 4095)歩あるいた時の位置,1つ左のピクセルが,(254, 1022, 4094)歩と,行程が続いています.
また,出発点からの距離の自乗を
D^[i]=distance
と表示させています.

それぞれの歩数における,距離自乗平均は,
256[歩] - 348[歩2]
1024[歩] - 1232[歩2]
4096[歩] - 4793[歩2]
でした.

これはどうなっているのかというと…

検証:

N歩あるいた時の出発点からの距離を,統計的に求めてみます.

Di
をi歩あるいた時の,出発点からの距離とします.
[DN2]
を求めます([X]はXの期待値です).
まず,
[D12]=1
は明らかです(0の地点から,1歩だけ歩いたから,距離の自乗は(±1)2=1).

そして,DNを,DN-1で表すと,
DN=
DN-1+1
or
DN-1-1
ですので,両辺自乗で,
DN2=
DN-12+2DN-1+1
or
DN-12-2DN-1+1
orを挟んだ2つの式は,どちらも等確率で起こるので,
DN2の期待値は,
[DN2]=
{[DN-12+2DN-1+1]+[DN-12-2DN-1+1]}/2
=[DN-12]+1
そして,[D12]=1より,
[DN2]=N
となります.

rms(二乗平均平方根)で表すと,
Drms=√N
となります.

結論が出ました.
ということで,実はN歩あるいた場合,出発点からの距離(の期待値)は√Nになるのでした.
先の実験結果を見ると,平均値は,期待値に"割と"近いことが分かります.

ちなみに,1ステップにおける歩数を,±1ではなく,[-1, +1]などにすると,より面白くなります.

2009年7月19日日曜日

2値化のガイドライン

面接官「特技は2値化とありますが?」
学生 「はい。2値化です。」
面接官「2値化とは何のことですか?」
学生 「画像処理です。」
面接官「え、画像処理?」
学生 「はい。画像処理です。グレースケール画像を白黒はっきりつける事が出来ます。」
面接官「・・・で、その2値化は当社において働くうえで何のメリットがあるとお考えですか?」
学生 「はい。グレースケール画像を2値化する際困りません。」
面接官「いや、当社には2値化をしようとする輩はいません。」
学生 「でも、2値化楽しいですよ。」
面接官「いや、楽しいとかそういう問題じゃなくてですね・・・」
学生 「誤差拡散法とかあるんですよ。」
面接官「ふざけないでください。それに誤差拡散法って何ですか。だいたい・・・」
学生 「誤差拡散法です。Error diffusion methodとも書きます。誤差というのは・・・」
面接官「聞いてません。帰って下さい。」
学生 「あれあれ?怒らせていいんですか?使いますよ。2値化。」
面接官「いいですよ。使って下さい。2値化とやらを。それで満足したら帰って下さい。」
学生 「運がよかったな。今日はグレースケール画像がないみたいだ。」
面接官「帰れよ。」