3週間目
ラベリング
画像の二値化を行うと黒いピクセルの海に白い島ができると考えられます。(その島の事を連続成分と言います。)その島々はテーブルの上に置かれたものかも知れません。各々の島を一つ一つの「もの」として解析したい場合、「ラベリング」を行わなければなりません。
「ラベリング」とは画像の二値化による白いピクセルの島をそれぞれ固有の値で塗りつぶす事です。ラベリングを行う事によって連続成分を一つ一つ解析することができます。

「cv.jit」では「cv.jit.label」がその処理をしてくれます。そのまま二値化画像を入力すると「long」のマトリックスが出力されます。2024までの連続成分を違う値で塗りつぶします。低い値で塗りつぶされた連続成分は見えにくいので「cv.jit.blobs.color」オブジェクトでランダムな色で表示すると分かりやすくなります。
連続成分は左上から数えられますので右下にある成分は値が高くなります。連続成分の位置が少しでも変わればその値が変わる事がありますので注意が必要です。
小さな島を無視する事もできます。「threshold」アトリビュートで連続成分の最低面積が指定できます。それ以下の面積の連続成分は消されますので強力なノイズフィルターにもなれます。
「long」データは多少扱いにくいので「char」の出力もできます。しかし、その場合、8ビットの数値で255までしか数えられないため連続成分が256個以上ありますと右下にあるのが消されます。「char」出力の指定は「@charmode 1」のアトリビュートで行います。
位置ではなく大きさによって連続成分の値が変わるモードもあります。初期値の「long」出力で、「@mode 1」を指定しますと、それぞれの連続成分が自分の面積で塗りつぶされます。その場合、同じ面積を持つ成分があればもちろん同じ値で塗りつぶされる事になります。「char」出力の場合「mode 1」は連続成分の面積ではなく大きさの順番で塗りつぶされます。最も大きい成分が「1」で2番目が「2」です。

連続成分の解析
ラベリングを行った後、連続成分をそれぞれ解析する事ができます。「cv.jit」では「cv.jit.blobs」から始まるオブジェクトはラベリングされた画像をこういう風に分析します。その場合、「cv.jit.label」の出力を必ず「char」に指定しないといけません。
「cv.jit.blobs」のオブジェクトは一次元のマトリックスを出力します。セル数は入力された画像の連続成分の数と同じです。それぞれのセルが一つの連続成分の解析結果を保管します。
「cv.jit.blobs.centroids」は連続成分の重心と重量を計算します。「cv.jit.blobs.centroids.draw」を使えば、任意の画像の上にそのデータを表示する事ができます。赤い十の字は重心を示し、緑の円はその下の連続成分と同じ面積(重量)を持ちます。

「cv.jit.blobs.bounds」は「jit.findbounds」と同様に連続成分を囲む箱の座標を返します。
「cv.jit.blobs.moments」で連続成分のモーメント解析ができます。「cv.jit.blobs.orientation」、「cv.jit.blobs.direction」又は「cv.jit.blobs.elongation」と併用すれば連続成分の形態特徴が分かります。それぞれに「.draw」オブジェクトもありますが、真ん中のインレットにモーメントを入力する必要があります。
連続成分の形態認識もできます。「cv.jit.learn」で予めモデルを学習させ、ファイルに保存すれば、「cv.jit.blobs.recon」オブジェクトにそのモデルを読み込みます。「cv.jit.blobs.recon」は比較モードしかありませんので自分で学習する事はできません。「cv.jit.blobs.moments」で計算されたモーメントを入力すれば、それぞれの連続成分を読み込まれたモデルに比較して、そのモデルからの距離を出力します。

ノイズ処理
二値化画像のノイズは形態解析に悪い影響を与える事があります。輪郭が複雑すぎたりすると本来同じ形を持つ画像が異なった解析結果を返す事もあります。ノイズをなくす方法は色々あります。例えば、照明を明るくすればカメラがもっと奇麗な画像を撮れます。しかし、それでもノイズが多い場合、形態的演算(morphological operation)が役に立ちます。
「cv.jit」で使える形態的演算は基本的に二つあります:浸食(erode)と膨張(dilate)。浸食とは二値化画像の白いピクセルの周囲に一つでも黒いピクセルがあれば、そのピクセルが黒くなります。その結果は輪郭のピクセルが全てなくなり、形が「浸食」します。膨張とはその逆です。黒いピクセルの周囲に一つでも白いピクセルがあれば白くなります。その結果、輪郭が太くなります。
浸食は白いノイズをなくして、膨張は黒いノイズをなくします。しかし、どれも解像度によって元の形に多少変化をもたらします。浸食を行った後、膨張を行えば元の形に近い画像が得られます。その処理を「オープン」と言います。膨張の後に浸食を行うのは「クローズ」です。
「cv.jit.erode」、「cv.jit.dilate」、「cv.jit.open」と「cv.jit.close」がそれらの処理を行います。
「@mode 1」とアトリビュートを指定しますと、周囲の定義を「上、右、下、左」にして十の字で画像を浸食・膨張させます。
色のフィルタリング
画像の二値化を行う時はただ明るさの強弱に閾値をつけて処理するだけでなく、様々な条件によってフィルタリングを行う事ができます。色を認識するのがその一つです。RGBデータを見れば、赤、緑と青のバランスが分かりますが、正確な色の認識はこの色空間なら難しいです。Jitterで予め指定された色と比較する時に「jit.chromakey」オブジェクトが役に立ちます。「Chromakey」とは本来グリーンスクリーンなでを使って、二つの画像を合成する方法です。しかし「jit.chromakey」に「@mode 1」を指定すれば、指定した色(「key」)との距離が計算されます。最も近いピクセルに255という値を付けたいので「@minkey 1. @maxkey 0.」を指定しなければなりません。「@tol」アトリビュートで閾値を変える事ができます。色の指定は「@color」アトリビュートですが、0ー255ではなく、0-1で指定されますので注意してください。「jit.suckah」オブジェクトを利用すればマウスでクリックするだけで色の指定が簡単にできます。


Leave a comment