JavaCVで画像を白黒に2値化にする方法を紹介します。
OCRする前に加工しておくと識字率が高くなったりするので事前処理として使用するといいでしょう。
以下の関連記事です。
- JavaCV(OpenCV)で特徴点マッチング
- JavaCV(OpenCV)で画像のリサイズ
- JavaCV(OpenCV)で画像のRGBを取得する
- JavaCV(OpenCV)でパノラマ合成(Stitching)
- JavaCV(OpenCV)で画像をグレースケール化
- JavaCV(OpenCV)で画像を結合する(VConcat, HConcat)
- JavaCV(OpenCV)で画像の切り出し
環境
- 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) を使用します。
引数については以下の通りです。
src | 2値化対象のMat |
dst | 2値化した画像を格納するMat |
thresh | 閾値 |
maxval | srcのピクセルが閾値を超えた場合に書き換える値 |
type | 閾値の処理方法 |
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 | 閾値を超えるピクセルは 閾値となり、それ以外のピクセルは変更されない |
全体ソースは以下
サンプルソースでは第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値化に使用する画像がこちらです。
THRESH_BINARYで2値化した画像が以下となります。
THRESH_BINARY_INV(THRESH_BINARYの逆パターン)だとこのようになります。
THRESH_OTSU ではこうなります。
THRESH_BINARYだと画像に合わせて閾値を探す必要がありますが THRESH_OTSU だと良い感じに2値化できます。
楽したいなら THRESH_OTSU でいいんじゃないでしょうか。
以上です。
コメント