2017年2月6日月曜日

閾値二値化(BinaryFilter)

 今回は二値化処理のなかで、指定閾値で二値化を行うBinaryFilterを実装します。BinaryFilterでは、あるピクセルについて輝度を計算し、その輝度が指定値以上ならばそのピクセルを白に、指定値以下ならそのピクセルを黒に変換する処理です。輝度の計算方法は複数ありますが、今回は計算速度を考慮した輝度計算を行います。なお、RGB値を輝度に変換し、それを新たなRGB値にする処理はグレースケール処理となります。
 まずは、 前回同様Tutorial1Activityクラスと同じ場所に、BinaryFilterクラスを作成します。その後以下のfilterメソッドを記述します。

    public int[] filter(int[] imageArray,int width, int height,int threshould) {
        int y_val = 0;
        int rgb = 0;
        int red = 0, green = 0, blue = 0;
        int[] oimgArray = new int[imageArray.length];//①
        for (int j = 0; j < imageArray.length; j++) {
            rgb = imageArray[j];
            red = (rgb >> 16) & 0xff;
            green = (rgb >> 8) & 0xff;
            blue = (rgb) & 0xff;
            y_val = ( 2 * red + 4 * green + blue ) / 7;//②
           if (y_val > threshould) {//③
                oimgArray[j] = 0xFFFFFFFF;
            } else {
                oimgArray[j] = 0xFF000000;
            }
        }
        return oimgArray;
    }


 ①では、出力用に画像のint配列と同じ長さの空の配列を作成します。
②では輝度を計算します。輝度の計算ではもっと厳密な計算式がありますが、②の計算式では小数点計算を行わなくてすむため、計算速度が速いです。なお、輝度やグレイスケール化については以下のHPをご覧ください。
http://daredemopc.blog51.fc2.com/blog-entry-877.html
 ③では得られた輝度と閾値を比較し、閾値より高い場合にはピクセルを白(255,255,255)に、閾値以下ならばピクセルを黒(0,0,0)にします。

 最後に、Tutorial1Activityクラスのint imageArray[]=ba2ia(ba);の下に以下の文を記入します。

      imageArray =new BinaryFilter().filter(imageArray, imagewidth, imageheight,120);

このとき、第4引数が閾値を示します。範囲を外れてもエラーは発生しませんが、基本的に閾値の範囲は0~254までとなります。
 以下に実機での実行結果を示します。閾値は120です。ヒストグラムからわかるように全てのピクセルが白または黒になっています。

0 件のコメント:

コメントを投稿