画像平面分割の高速化(2)
2009/12/21 21:18 - AS3.0
前回のあらすじ。
BitmapData の一定領域について、輝度の標準偏差や平均色を求めようと思ったら、全ピクセルを検査しなきゃいけない。 となると全ピクセル走査をおこなう必要があるんだけど、もっと簡単な方法で同様な処理ができないものか。
そう考えていたときに彼との運命的な出逢いが訪れた。彼の名は BitmapData.histogram!
BitmapData.histogram を使ったビジュアル的に分かりやすい事例は Flash 10: new method BitmapData.histogram();(from Pixelero)を見てたもれ。
ちなみに "Foundation ActionScript 3.0 Image Effects" だったらP212~216 にサンプルコード付きで説明がありますよ。
で、こいつは何をしてくれるのかというと、色の分布状況をデータとして出力してくれるヤツです。
二次元 Vector という、なかなか珍しいものが返り値になってます。 要素数256個の Vecotr.<Number> を4つ格納した Vector という構造。
じゃあその返り値の二次元 Vector は何を表しているのか、というと以下のとおり。
Vector[0] : 赤の分布状況 Vector[1] : 緑の分布状況 Vector[2] : 青の分布状況 Vector[3] : アルファ値の分布状況
では、それぞれの Vector はどうなっているのか。 肝は要素数が256個という点です。色で256というと何か? そう、色の段階ですね。 今さら言うまでもないことですが、色の3原色の各要素は、それぞれ最小値が0、最大値が255という256の段階を持っています。
Vector のインデックスは、この色の段階に対応しているんです。 じゃあ格納される値は何なのか。
赤についてのみ見てみましょう。Vector[0] を rVector 置き換え、サイズが 100 pixel の BimtapData について例示します。
全てのピクセルが黒(0x000000)の場合。
rVector[0] = 100 rVector[1] ~rVector[255] は全て 0
全てのピクセルが赤(0xFF0000)の場合。
rVector[0] ~ rVector[254] は全て 0 rVector[255] = 100
半分が黒、半分が赤の場合。
rVector[0] = 50 rVector[1] ~ Vector[254] は全て 0 rVector[255] = 50
とまぁこのように、Vector に格納されるのはピクセル数なんです。 つまり、RGB 三原色およびアルファ値について、対象の BimtpData 内で、どの色が何ピクセル使われているかを知らせてくれるメソッドが BitmapData.histogram なんです。
検査対象の BitmapData が何ピクセルであろうとも、要素数256個の Vector 4つに還元してくれます。
これはつまり、BitmapData が何ピクセルであろうと、走査ループの回数を256回で済ますことができるようになる、ということです。
BitmapData の領域が小さい場合は逆効果になったりするかも知れませんが、大きな領域の場合の効果は絶大であることが期待できます。
前回、wonderfl のステージ領域の全ピクセルを1個ずつ走査すると約22万回ループしなければならないと書きましたが、BitmapData.histgram を使った場合、その 0.1 %のループ数にできるわけです。
実に素晴らしいメソッドじゃあありませんか。
続く。