Let's write β

プログラミング中にできたことか、思ったこととか

VisualWorksで画像閾値処理

 夜中の更新になりますが、僕に取っては昼間よりも夜の方が集中しやすいので...



Smalltalkで画像の閾値処理(2値化とも)をやってみました。いろんなSmalltalk界の有名人の方(sumimさんや、umejavaさん)にお世話になっていて申し訳ない気持ちです...

imgReader := ImageReader fromFile: '/path/to/your/image/file'.
img := imgReader image.
newImage := img copyEmpty.
rgbAve := 0.
0 to: (img width - 1) do: [:x |
	0 to: (img height - 1) do: [:y |
		r := (img valueAtPoint: x@y) red.
		g := (img valueAtPoint: x@y) green.
		b := (img valueAtPoint: x@y) blue.
		rgbAve := (r + g + b) / 3.	
		rgbAve>0.3 ifTrue: [ newImage valueAtPoint: x@y put: (ColorValue red: 1.0 green: 1.0 blue: 1.0)] 
							ifFalse: [newImage valueAtPoint: x@y put: (ColorValue red: 0.0 green: 0.0 blue: 0.0)].
	].
].
img inspect.
newImage inspect.

まだ、変換後の画像をinspectしているだけです(どうやって画像をファイルに書き出すのか知らないので...orz)
とりあえず変換ができている確認はとれました。



 パラメータとしてはifTrueの当たりの0.3とかが味噌です。VWではRGBは0〜255よりも0〜1.0の方が一般的です。(まぁ255のほうは一貫性ないですし。(255のとこが))こっちの方が正しい気もします。 話がそれました..0.3のところがいわゆる閾値になっています。これをいじると白と黒に分岐する明度の閾値を変更できます。


 こういった処理を書いたときに他の言語ならどうするのでしょうか?通常はライブラリとかにするんじゃないでしょうか?Smalltalkの場合は違います。直接Imageクラスにメッセージを追加します。こういう所も「ユーザー主体の開発スタイル」かも知れませんね。(Dynabook的ですなぁ)


 僕が作ろうと思ったメッセージは2つ、まずColorValue(img valueAtPoint: aPoint で帰ってくる色データのオブジェクトのクラス)にrgb明度のAvarageを返すメッセージを追加,
 次に、それをつかって、画像をrgbを基準に閾値処理するメッセージを追加。といったところです。これぐらいがそれぞれのオブジェクトの責任を分担できているのではないかと思います。