二値化(1)
2010/03/05 22:42 - AS3.0
画像処理シリーズ、今回から二値化についての話。
今更いうまでもないでしょうが、二値化というのは、以下のように定義できます。
このシリーズを学ぶにあたって参考にしている画像処理本を見ると、もっぱら1ピクセルずつ走査するアルゴリズムが記載されています。
「C言語で学ぶ実践画像処理」では、閾値を場所によって変えるというヘビーな解説(P26)もあったりします。
でも、当ブログで扱う言語は ActionScript 3.0。 ActionScript 3.0 で二値化ならそんな面倒なことしないでオッケー。 BitmapData#threshold というメソッドを使うことで、簡単に二値化が実現できるのは皆さま先刻ご承知のとおりです。
しかし「簡単に」というのはあくまでコーディング記述が簡潔におこなえるという意味であり、使いこなすという意味では、むしろ難しいメソッドと言ってよろしい。
"Foundation ActionScript 3.0 Image Effects" には『BitmapData に備わったメソッド中もっとも複雑なものの一つであることは間違いない』と記されています(P216)。
ここで threshold() の引数を見てみます。
- sourceBitmapData:BitmapData
- sourceRect:Rectangle
- destPoint:Point
- operation:String
- threshold:uint
- color:uint (default = 0)
- mask:uint (default = 0xFFFFFFFF)
- copySource:Boolean (default = false)
第1~3引数までは、applayFilter、copyChannels、paletteMap、pixelDissolve 等々々、BitmapData のメソッドに頻出するものなので、特に説明は不要でしょう。
第5引数はこのメソッドの主役である閾値。 第4引数はその閾値と各ピクセルの色をどのように比較するかという演算子。 第6引数はその比較結果にマッチしたピクセルに適用される色。
第8引数は割愛。
問題なのは第7引数の mask です。
ワタクシこの mask がイマイチよく理解できていません。
LiveDoc には『カラーコンポーネントを分離するために使用するマスク』と書かれています。
この値を 0x00FF0000、0x0000FF00、0x000000FF のように、RED、GREEN、BLUE に対応させるのは理解できます。
→はそのようなサンプルです。
上段が原画、下段が二値化した画像、Threshold 処理により、閾値より大きい場合は山吹色、そうでないときは黒にするようにしています。
ラジオボタンで RED、GREEN、BLUE を切り替えることができます。 切り替えたときに設定される閾値とマスクはその下に表示されます。
RED 選択時は赤の帯と灰色の帯の部分が、GREEN 選択時は緑と灰色の帯の部分が、BLUE 選択時は青と灰色の帯の部分が、スライドバーを動かしたときに変化します。
このように各色要素一つずつ扱う場合は理解できるんです。
でもマスクの既定値って 0xFFFFFFFF ですよね。複数の色要素に 0xFF を割り当てる(フラグを立てる)、ってどういう状況なんすかね? それがよく分からん。
0xFFFFFFFF が使えるなら 0x00FF00FF みたいなマスクの使い方もできると思うんですけど、ってワケで、上のサンプルのラジオボタンをチェックボックスに置き換えたサンプルが→です。
それぞれの色要素を1個ずつ選んだときはラジオボタンのときと同じ挙動をするのは当然ですよね。 じゃあ複数の色要素を選んだ時はどうなのか。
たとえば RED と BLUE を選んだときは、赤の帯、青の帯、灰色の帯の三つの帯の部分がスライダーに伴って変化するだろうと予想するんですが、実際にはそうなりません。RED だけを選んだときの挙動と同じです。そして閾値が 0 に振り切ったときのみ青の帯部分が山吹色に急に切り替わります。
複数の色要素を選んだときは上位ビットの色要素のみが期待どおりの動作をします。何でやねん。
どっかコーディングミスしてるんですかねー。それともそもそもオレちゃん何か勘違いしてる? どなたかご教示いただけたら幸い。
でもまあ二値化は前処理にグレイスケールをするもんだから、こんなこと考える必要ないっすかねー。