OpenCVによる画像の2値化

文書をとりあえず写真に撮って、後でモノクロ2値化したいことがある。そのために簡単に使えるPythonのプログラムを作っておく。

アルゴリズムは OpenCV の Image Thresholding の真ん中あたりに載っている三つのアルゴリズムの比較の図を参考にして、Adaptive Gaussian Thresholding にする。これは、まずグレースケール化して、近傍 blockSize × blockSize の領域の平均の明るさ(ただし Gaussian の重みをつけて平均する)から定数 C を引いた値を閾値として2値化する。

使い方は、次のコードを例えば thresh.py とし、ターミナルで thresh.py 入力ファイル 出力ファイル [blockSize] [C] として起動する。最後の二つはオプションで、blockSize は奇数とする(偶数を与えても奇数にする)。うまくいかないようであれば特に blockSize を調節するとよい。

#! /usr/bin/env python3

import sys
import cv2

blockSize = 51
C = 20

if len(sys.argv) < 3:
    print(sys.argv[0], f"infile outfile [blockSize={blockSize}] [C={C}]")
    exit()

infile = sys.argv[1]
outfile = sys.argv[2]
if len(sys.argv) > 3:
    blockSize = int(sys.argv[3]) // 2 * 2 + 1  # odd number
if len(sys.argv) > 4:
    C = int(sys.argv[4])

img = cv2.imread(infile)
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img = cv2.adaptiveThreshold(
    img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
    cv2.THRESH_BINARY, blockSize, C)

cv2.imwrite(outfile, img)