OpenCV

【OpenCV/Python】adaptiveThresholdの処理アルゴリズム

自動でしきい値を決めて二値化してくれる画像処理と言えば、大津の二値化ですが、OpenCVにはadaptiveThreshold(適応的しきい値処理)という良さげな処理があります。

この adaptiveThreshold は画像全体に影や照明のムラがある場合に、効果を発揮します。

 

以下に大津の二値化とadaptiveThreshold の処理例を示します。

 

使用したプログラム

import cv2

img = cv2.imread("image.jpg")
# カラー→モノクロ変換
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 元画像の表示
cv2.imshow("src image", img)

# 大津の二値化
_, dst1 = cv2.threshold(
    img, 0, 255, cv2.THRESH_OTSU)
cv2.imshow("THRESH_OTSU", dst1)

# 適応的しきい値処理
dst2 = cv2.adaptiveThreshold(
    img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
    cv2.THRESH_BINARY, 51, 20)
cv2.imshow("adaptiveThreshold", dst2)

cv2.waitKey(0)

元画像

OpenCV adaptiveThresholdの処理アルゴリズム

大津の二値化

OpenCV adaptiveThresholdの処理アルゴリズム

adaptiveThreshold

OpenCV adaptiveThresholdの処理アルゴリズム

 

 

元画像の左側に影のある例を示しています。

今回の画像は、文字の部分を黒く、それ以外の部分を白く二値化することを想定しているのですが、大津の二値化では、自動でしきい値は決めてくれるものの、画像全体に輝度値のムラがある場合は、うまく二値化してくれません。それに比べて adaptiveThreshold ではある程度狙った通りに二値化されています。

 

Pythonですが、この関数定義は以下のようになっています。

adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C)
src 入力画像
maxValue 二値化後の輝度値
adaptiveMethod 適応的しきい値処理で使用するアルゴリズム

cv2.ADAPTIVE_THRESH_MEAN_C
もしくは

cv2.ADAPTIVE_THRESH_GAUSSIAN_C
thresholdType 二値化の種類
cv2.THRESH_BINARY
もしくは

cv2.THRESH_BINARY_INV
blockSize しきい値計算のための近傍サイズ
C 平均あるいは加重平均から引かれる値
戻り値 処理後画像

(参考)

その他の画像変換 — opencv 2.2 documentation

 

だいたい上記のような説明されている場合が多いのですが、よく分からないですよね?!

ただ、やっている事自体は意外と簡単です。

実際にOpenCV内部で行われている処理と異なると思いますが、処理の意味合い的には以下の通りになります。

 

1.adaptiveMethodの設定に従って、平均化(blur)もしくはガウシアンフィルタ(GaussianBlur)で入力画像をぼかします。この時のカーネルのサイズが blockSize x blockSize となります。

OpenCV adaptiveThresholdの処理アルゴリズム

 

2.元画像とぼかした画像の差分処理を行います。

OpenCV adaptiveThresholdの処理アルゴリズム

 

3.差分画像を指定したしきい値( C ) で二値化し、白黒反転します。

OpenCV adaptiveThresholdの処理アルゴリズム

 

すると、adaptiveThreshold で処理した二値化画像が取得できます。
重要なのは、処理の途中に平均化 もしくは ガウシアンフィルタで二値化したい部分をぼかしている部分です。そのため、二値化したい部分の大きさ(今回の例では文字の線幅)に対して十分大きな blockSize を指定する必要があります。

blockSizeを変えながら処理をすると、

blockSize = 5 のとき

OpenCV adaptiveThresholdの処理アルゴリズム

blockSize = 21 のとき

OpenCV adaptiveThresholdの処理アルゴリズム

blockSize = 51 のとき

OpenCV adaptiveThresholdの処理アルゴリズム

 

このようにblockSizeが小さいと、文字の輪郭が二値化され、blockSizeを大きくすると、太い文字も文字全体が二値化されます。

処理の目的的にはトップハットボトムハットに似ています。

(参考)

膨張・収縮・オープニング・クロージング
膨張・収縮処理では一般的に二値化された白黒の画像に対して処理が行われ、 注目画素の周辺に1画素でも白い画素があれば...

 

実際の用途的には、画像にムラがあるときに、小さなゴミやキズなどの検出に用いられます。
逆に大きな領域を二値化する場合には adaptiveThreshold は不向きなのでご注意下さい。

 

ちなみに買ったチョコビ

OpenCV adaptiveThresholdの処理アルゴリズム

コメント

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