画像の2値化は 閾(しきい)値処理をして 画像を白と黒の色だけで表現された2階調の二値画像にすることです。OpenCv for Androidでは Imgprocクラスのthresholdメソッドで閾値処理を行います。
Imgproc.threshold(Mat src, Mat dst, double thresh, double maxval, int type)
- src 2値化処理前のMat
- dst 2値化処理後のMat
- thresh 閾値
- maxval 変換指定値
- type 以下に示す 変換手法(Imgprocクラスの定数として定義されています)
- THRESH_BINARY:閾値以下の値は0に,それ以外は指定した値(maxVal)になります.
- THRESH_BINARY_INV:上記とは逆に,閾値より大きい値が0に,それ以外は指定した値(maxVal)になります.
- THRESH_TRUNC:閾値より大きい値は閾値まで切り詰められ,それ以外はそのまま残ります.
- THRESH_TOZERO:閾値より大きい値はそのまま残り,それ以外は0になります.
- THRESH_TOZERO_INV:上記とは逆に,閾値以下の値はそのまま残り,それ以外は0になります.
また 特殊な値 THRESH_OTSU を用いると、関数は大津のアルゴリズムを用いて最適な閾値を決定し,それを引数 thresh で指定された値の代わりに利用します.つまり,自分で閾値を決める必要がありません.
以下に実行結果を示します。
(1)元の画像 | (2)グレースケール |
(3)THRESH_BINARY | (4)THRESH_BINARY_INV |
(5)グレースケール | (6)THRESH_TRUNC |
(7)THRESH_TOZERO | (8)THRESH_TOZERO_INV |
変換処理のコーディングは以下の通りです。
(3)Imgproc.threshold(mat, mat_bin, 0.0, 255.0, Imgproc.THRESH_BINARY | Imgproc.THRESH_OTSU);
(4)Imgproc.threshold(mat, mat_bininv, 0.0, 255.0, Imgproc.THRESH_BINARY_INV | Imgproc.THRESH_OTSU);
(6)Imgproc.threshold(mat, mat_trunc, 0, 255, Imgproc.THRESH_TRUNC | Imgproc.THRESH_OTSU);
(7)Imgproc.threshold(mat, mat_tozero, 0, 255, Imgproc.THRESH_TOZERO | Imgproc.THRESH_OTSU);
(8)Imgproc.threshold(mat, mat_tozeroinv, 0, 255, Imgproc.THRESH_TOZERO_INV | Imgproc.THRESH_OTSU);
処理の順番は以下の順番で行わないと エラーになったり 何も表示されない現象が発生します。(ここを参照)
a. BitmapからMatに変換
Mat mat = android.BitmapToMat(src2);
b. グレースケール化
Imgproc.cvtColor(mat , mat, Imgproc.COLOR_RGB2GRAY);
c. 2値化
Imgproc.threshold(mat, mat_bin, 0.0, 255.0, Imgproc.THRESH_BINARY | Imgproc.THRESH_OTSU);
d. BGRAに変換
Imgproc.cvtColor(mat_bin, mat_bin, Imgproc.COLOR_GRAY2BGRA,4);
e. BitMapに変換
android.MatToBitmap(mat_bininv, bmp_bininv);
【adaptiveThresholdメソッド】 |
OpenCvでは2値化を行うもうひとつの方法に ImgprocクラスのadaptiveThresholdメソッドを使う方法があります。
OpenCv Cookbookによると 『adaptiveThresholdは、適応的な閾値処理を行います。この適応的というのは,閾値が入力によって適応的に決まることを意味します。』とあります。
適応的とはadaptiveの直訳で、日本語らしく無い表現で意味がよくわかりません。、『入力に応じて 適切に閾値を求める』と理解すればよさそうで、実際には対象となるピクセルの近傍のピクセルの平均値をもとに閾値が求められます。
adaptiveThreshold(Mat src, Mat dst, double maxValue, int adaptiveMethod, int thresholdType, int blockSize, double C)
- src 2値化処理前のMat
- dst 2値化処理後のMat
- maxValue 条件を満たすピクセルに割り当てられる値
- adaptiveMethod 閾値決定の手法
- thresholdType 変換手法 THRESH_BINARYまたはTHRESH_BINARY_INV
- blockSize 対象のピクセルの近傍何ピクセルを元に平均値を求めるかを示す(奇数のみ可)
- C
- ADAPTIVE_THRESH_MEAN_C:閾値 T(x,y) は,(x,y) の近傍 blockSize * blockSize の平均から C を引いた値
- ADAPTIVE_THRESH_GAUSSIAN_C:閾値 T(x,y) は,(x,y) の近傍 blockSize x blockSize の(ガウス分布を用いた)加重平均から C を引いた値になります.このガウス分布の標準偏差は,blockSize から決定されます.
(1)MEAN blockSize=7 C=2 | (2)GAUSSIAN blockSize=7 C=2 |
(3)MEAN blockSize=15 C=8 | (4)GAUSSIAN blockSize=15 C=8 |
- Imgproc.adaptiveThreshold(mat, mat_mean72, 255.0, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY, 7, 2);
- Imgproc.adaptiveThreshold(mat, mat_gaussin72, 255.0, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C, Imgproc.THRESH_BINARY, 7, 2);
- Imgproc.adaptiveThreshold(mat, mat_mean158, 255.0, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY, 15, 8);
- Imgproc.adaptiveThreshold(mat, mat_gaussin158, 255.0, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C, Imgproc.THRESH_BINARY, 15, 8);
BlockSizeを大きくすると ノイズが消えてこの例では輪郭がはっきりしてくる感じがします。
by Android2.2 with OpenCv 2.3.1 for Android |