Hatena::ブログ(Diary)

flashrod このページをアンテナに追加 RSSフィード

2006-11-17 モルフォロジ処理

[] AS3で画像処理入門(その2) 22:52  AS3で画像処理入門(その2)を含むブックマーク

前回2値化グレースケールエッジ検出 - flashrodに引き続き、画像処理入門なのだ。

今回はモルフォロジ処理というやつだ。参考にしたのはこんなところ。

Dilate (膨張)

前にやったMedianSmoothと処理は良く似ている。構成要素とかカーネルというやつは、とりあえず3x3の十字でやる。この十字に含まれる画素のうち、最大の明るさの値を採用することにする。

        /** 膨張
         * @param dst デスティネーション
         * @param src ソース
         */
        public function Dilate(dst:BitmapData, src:BitmapData):void {
            for (var x:int = 0; x < src.width; x++) {
                for (var y:int = 0; y < src.height; y++) {
                    var max:int = 0, c:int;
                    c = src.getPixel(x - 1, y) & 255;
                    max = c > max ? c : max;
                    c = src.getPixel(x, y - 1) & 255;
                    max = c > max ? c : max;
                    c = src.getPixel(x, y) & 255;
                    max = c > max ? c : max;
                    c = src.getPixel(x, y + 1) & 255;
                    max = c > max ? c : max;
                    c = src.getPixel(x + 1, y) & 255;
                    max = c > max ? c : max;
                    dst.setPixel(x, y, (max << 16) | (max << 8) | max);
                }
            }
        }

ソースとデスティネーションは同じ高さと幅でなければならない。ソースはグレースケールであることを前提にしているので、青成分しか見てない。

Dilateの結果は白い部分が広がる。ということは小さい黒い点なんか無くなる。上に掲げたOpenCVの解説ページに処理前後の絵があって分かりやすい。

Erode (収縮)

Dilateとの違いは、最小の明るさを採るところだけ。あとは同じ。

        /** 収縮
         * @param dst デスティネーション
         * @param src ソース
         */
        public function Erode(dst:BitmapData, src:BitmapData):void {
            for (var x:int = 0; x < src.width; x++) {
                for (var y:int = 0; y < src.height; y++) {
                    var min:int = 255, c:int;
                    c = src.getPixel(x - 1, y) & 255;
                    min = c < min ? c : min;
                    c = src.getPixel(x, y - 1) & 255;
                    min = c < min ? c : min;
                    c = src.getPixel(x, y) & 255;
                    min = c < min ? c : min;
                    c = src.getPixel(x, y + 1) & 255;
                    min = c < min ? c : min;
                    c = src.getPixel(x + 1, y) & 255;
                    min = c < min ? c : min;
                    dst.setPixel(x, y, (min << 16) | (min << 8) | min);
                }
            }
        }

Erodeの結果は黒い部分が広がる。

Open (切断)

openはerodeしてdilateすればよい。

        /** 切断
         * @param dst デスティネーション
         * @param src ソース
         */
        public function Open(dst:BitmapData, src:BitmapData):void {
            var tmp:BitmapData = new BitmapData(src.width, src.height);
            Erode(tmp, src);
            Dilate(dst, tmp);
        }

Openの結果は、黒背景の白細線が切断される。


Close (接続)

closeはopenと逆で、dilateしてerodeすればよい。

        /** 接続
         * @param dst デスティネーション
         * @param src ソース
         */
        public function Close(dst:BitmapData, src:BitmapData):void {
            var tmp:BitmapData = new BitmapData(src.width, src.height);
            Dilate(tmp, src);
            Erode(dst, tmp);
        }

Closeの結果は、黒背景で近くに有る白いオブジェクト同士がつながる。