2017年2月7日火曜日

二値画像の収縮処理(ErosionFilter)

 今回は二値画像の収縮処理を実装します。収縮処理とは、二値画像における処理方法のひとつで、各ピクセルについてそのピクセルと周囲のピクセルを調べ、一つでも黒色があるならば黒色に変換する処理です。そのため、処理の後は基本的に黒色が増えます。具体的な処理などは以下のHPを参照してください。
http://imagingsolution.blog107.fc2.com/blog-entry-101.html

プログラムのコーディングに移ります。 Tutorial1Activityクラスと同じ場所にErosionFilterクラスを作成します。その後、filterメソッドに以下のコードを入力します。
    public int[] filter(int[] imageArray, int width, int height,int n) {
        int[] oimgArray = new int[imageArray.length];
        for(int nth=0;nth < n;nth++){//①
            int[] blackArray=new int[imageArray.length];//②
            for(int i =0;i < imageArray.length;i++){
                blackArray[i]=imageArray[i]& 0xff;//③
            }
            for (int x = 1; x < width-1; x++) {
                for (int y = 1; y < height-1; y++) {
                    int black=blackArray[x + y * width]*blackArray[x + y * width+1]*blackArray[x + y * width-1]
                            *blackArray[x + (y-1) * width]*blackArray[x + (y+1) * width]
                            *blackArray[x + (y-1) * width+1]*blackArray[x + (y-1) * width-1]
                            *blackArray[x + (y+1) * width+1]*blackArray[x + (y+1) * width-1];//④
                    if(black > 0){//⑤
                        oimgArray[x + y * width] = 0xFFFFFFFF;
                    }else{
                        oimgArray[x + y * width] = 0xFF000000;
                    }
                }
            }
            for (int i = 0; i < imageArray.length; i++) {
                if (oimgArray[i]==0) {
                    oimgArray[i] = 0xFFFFFFFF;//⑥
                }
            }
            imageArray=oimgArray;//⑦
        }
        return oimgArray;
    }

 ①は収縮処理の繰り返し処理です。メソッドの第四引数の数だけ収縮処理を繰り返します。
 ②は 白黒の情報のみを持つ配列です。③によって入力用配列であるimageArrayから白(255)または黒(0)の情報を得て格納します。
 ④では、各ピクセルとその周囲のピクセルについて、白黒の値の論理積を求めます。このとき、白がいくつあっても黒が一つでもあれば④の答えは0となります。逆にすべてのピクセルが白の場合は答えは0より大きな値になります。
 ⑤では④の答えから0より大きい場合には出力用配列に白の情報を格納し、0であるならば黒の情報を格納します。
 ⑥では④で処理の行わなかった画像の一番外側について白の情報を格納します。
 ⑦では出力用配列を入力用配列にコピーし、繰り返し処理ができるようにしています。

 Tutorial1ActivityクラスにErosionFilterを記入する際には必ず二値処理の後に加えます。今回は以下のような順番で記載しました。
imageArray =new PTileFilter().filter(imageArray, imagewidth, imageheight,50);
imageArray =new ErosionFilter().filter(imageArray, imagewidth, imageheight, 2);
imageArray =new HistogramFilter().filter(imageArray, imagewidth, imageheight);

ErosionFilterの第四引数は収縮回数を示しており、回数だけ収縮処理が繰り返されます。この例では2回繰り返されます。
 以下に実機での実行結果を示します。繰り返し回数は2です。Pタイル法フィルターの実行結果に比べて黒が増えていることがわかります。ヒストグラムでも0(黒)のバーが長く、255(白)のバーが短くなっています。


0 件のコメント:

コメントを投稿