本ブログはアフィリエイト広告を利用しています。

JavaCV(OpenCV)で画像を2値化(白黒化)する

dolphin プログラミング

JavaCVで画像を白黒に2値化にする方法を紹介します。
OCRする前に加工しておくと識字率が高くなったりするので事前処理として使用するといいでしょう。
以下の関連記事です。

環境

  • Windows10 Pro
  • Spring Boot 2.5.3
  • JDK 11

pom.xml

pomでJavaCVのjarを読み込みます。

<!-- https://mvnrepository.com/artifact/org.bytedeco/javacv-platform -->
<dependency>
    <groupId>org.bytedeco</groupId>
    <artifactId>javacv-platform</artifactId>
    <version>1.5.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.bytedeco/javacv -->
<dependency>
    <groupId>org.bytedeco</groupId>
    <artifactId>javacv</artifactId>
    <version>1.5.6</version>
</dependency>

JavaCVで2値化

画像の2値化を行うには一旦グレースケール化した後、org.bytedeco.opencv.global.opencv_imgproc.threshold (Mat src, Mat dst, double thresh, double maxval, int type) を使用します。
引数については以下の通りです。

src2値化対象のMat
dst2値化した画像を格納するMat
thresh閾値
maxvalsrcのピクセルが閾値を超えた場合に書き換える値
type閾値の処理方法
thresholdの引数

typeについては以下となります。
org.bytedeco.opencv.global.opencv_imgproc内に定義があります。

THRESH_BINARY閾値を超えるピクセルは 第三引数で設定した値になり、それ以外のピクセルは0になる
THRESH_BINARY_INV THRESH_BINARYの逆パターン
閾値を超えるピクセルは0になり、それ以外のピクセルは第三引数で設定した値になる
THRESH_OTSU大津方式により自動で閾値を設定する
THRESH_TOZERO閾値を超えるピクセルは無変更で、それ以外のピクセルが0になる
THRESH_TOZERO_INV THRESH_TOZEROの逆パターン
閾値を超えるピクセルは0で、それ以外のピクセルが無変更になる
THRESH_TRIANGLEトライアングル方式により自動で閾値を設定する
THRESH_TRUNC閾値を超えるピクセルは 閾値となり、それ以外のピクセルは変更されない
thresholdの第5引数に指定する値

全体ソースは以下
サンプルソースでは第3引数を255としているため真っ黒(0)と真っ白(255)となりますが、ここは好きに変えても大丈夫です。差をはっきりさせるための2値化だと思うので変更する必要もないかもですが。

import static org.bytedeco.opencv.global.opencv_imgcodecs.*;
import static org.bytedeco.opencv.global.opencv_imgproc.*;

import org.bytedeco.opencv.opencv_core.Mat;
import org.junit.jupiter.api.Test;

class OpenCVUtilTest {

    @Test
    void testBinarization() {
        try (Mat mat = imread("C:\\gomibako\\stitching_org.jpg");
                Mat grayMat = new Mat();
                Mat binMat = new Mat()) {

            // グレースケール化
            cvtColor(mat, grayMat, CV_BGR2GRAY);

            // 2値化
            org.bytedeco.opencv.global.opencv_imgproc.threshold(grayMat, binMat, 100, 255, THRESH_BINARY);

            imwrite("C:\\gomibako\\bin.jpg", binMat);
        }
    }
}

実行結果

2値化に使用する画像がこちらです。

dolphin

THRESH_BINARYで2値化した画像が以下となります。

THRESH_BINARY_INV(THRESH_BINARYの逆パターン)だとこのようになります。

THRESH_OTSU ではこうなります。
THRESH_BINARYだと画像に合わせて閾値を探す必要がありますが THRESH_OTSU だと良い感じに2値化できます。
楽したいなら THRESH_OTSU でいいんじゃないでしょうか。

以上です。

コメント

タイトルとURLをコピーしました