OpenCV

画像処理 「OpenCV 4」 大津の二値化

しきい値処理の値は任意の値を設定できます。しかし、どの値を設定すればいいのでしょうか。
試しながら良い値を見つけるというのも一つですが、それでは時間と手間がかかります。

今回は、二値化処理でぜひ試してみたい、大津の二値化処理を試してみます。

準備

入力画像のヒストグラムが二峰性(凸が二つ)を持つような画像(bimodal image)に対して有効です。

ヒストグラムの例

ざっくりと、「二つのピークの間の値をしきい値として使用する」処理です。

cv2.threshold 関数の二つ目の出力 retVal は、今回説明する、大津の二値化で使うことができます。しきい値は0を指定します。計算されたしきい値がretValとして返ります。

サンプルコード

しきい値を127に設定した単純なしきい値処理

import cv2
import numpy as np
import matplotlib.pyplot as plt

image = cv2.imread("image.png", 0)

ret, th = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY)

plt.subplot(1, 2, 1)
plt.title("original")
plt.imshow(image, 'gray')
plt.xticks([])
plt.yticks([])
plt.subplot(1, 2, 2)
plt.title("result")
plt.imshow(th, 'gray')
plt.xticks([])
plt.yticks([])
plt.show()
実行結果

大津の二値化を適用

import cv2
import numpy as np
import matplotlib.pyplot as plt

image = cv2.imread("image.png", 0)

ret, th = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)

plt.subplot(1, 2, 1)
plt.title("original")
plt.imshow(image, 'gray')
plt.xticks([])
plt.yticks([])
plt.subplot(1, 2, 2)
plt.title("result")
plt.imshow(th, 'gray')
plt.xticks([])
plt.yticks([])
plt.show()
実行結果

続けて、もう少し応用することを考えます。

平滑化処理によってノイズの影響を軽減してから大津の二値化を適用

import cv2
import numpy as np
import matplotlib.pyplot as plt

image = cv2.imread("image.png", 0)

blur = cv2.GaussianBlur(image, (5, 5), 0)
ret, th = cv2.threshold(blur, 127, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)

plt.subplot(1, 2, 1)
plt.title("original")
plt.imshow(blur, 'gray')
plt.xticks([])
plt.yticks([])
plt.subplot(1, 2, 2)
plt.title("result")
plt.imshow(th, 'gray')
plt.xticks([])
plt.yticks([])
plt.show()
実行結果