Pythonで画像を2値化する(OpenCV編)

PythonのOpenCV(cv2)モジュールを使って、画像の2値化をします。

画像の2値化方法

カラーまたはグレースケールの画像を白か黒かの2値の画像に変換します。

手順としては、最初にグレースケールに変換して、その後に白黒の2値画像に変換します。

グレースケールへの変換については、 以前の投稿 を参考にしてください。

2値化にはthresholdメソッドを使用します。

retval, dst = cv2.threshold(src, thresh, maxval, type)
変数 内容
src ndarray 変換される画像データ。
thresh float 閾値。
maxval float THRESH_BINARYモードで出力するときの最大値。
type   画素の白黒判定をするときのモード。
retval float 変換に使用した閾値。
dst ndarray 変換後の画像データ。

8ビットのグレースケール画像では、1画素の白黒の濃淡が0~255の数値で表されます。ある数値(閾値)を決めて、それより数値が小さい画素は0(黒)に、それより数値が大きい画素は255(白)に変換します。

このモードの2値化をするときは、typeにTHRESH_BINARYまたはTHRESH_BINARY_INVを指定します。(INVは白黒反転します。)

試してみましょう。

プロ生ちゃん の画像を2値化してみます。

元画像はこちらです。

元画像

コードはこんな感じです。

import cv2

im = cv2.imread('original.png', cv2.IMREAD_GRAYSCALE)

retval, dst = cv2.threshold(im, 128, 255, cv2.THRESH_BINARY)

cv2.imwrite('result.png', dst)

画像ファイルを読み込むときにグレースケールにしてしまいます。

出力はこうなります。

元画像

ちょっと白いですね。threshの値を調整しなければなりません。

この調整を自動的に行う方法として、typeに指定を追加する方法があります。

import cv2

im = cv2.imread('original.png', cv2.IMREAD_GRAYSCALE)

retval, dst = cv2.threshold(im, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

print(retval)
cv2.imwrite('result.png', dst)
大津の方法
174.0

なかなか良い感じです。

THRESH_OTSUというのは 大津の方法 による閾値の自動計算を指定するものです。簡単に言うと、画像全体を濃淡のヒストグラムにしてそのバランスを探すようなイメージです。

閾値がretvalに返されます。今回は174.0でした。

閾値を自動計算する方法がもう一つあります。トライアングルアルゴリズムです。

import cv2

im = cv2.imread('original.png', cv2.IMREAD_GRAYSCALE)

retval, dst = cv2.threshold(im, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_TRIANGLE)

print(retval)
cv2.imwrite('result.png', dst)
トライアングル
232.0

濃淡がはっきりしている画像の場合は、大津の方法の方が良さそうですね。

広告

Pythonで画像処理カテゴリの投稿