OpenCVの使い方6 ~ 2値化処理
OpenCVの使用方法について、今回は画像の2値化処理について紹介したい。
1. 基本的な2値化処理
単純な2値化処理はある閾値を設定して、グレースケール(モノクロ)画像に対して閾値より大きければ白(255)、小さければ黒(0)を割り当てる。
以下Google Colabで画像をアップロードして読み込ませて、グレースケール画像データgray
を生成するまでのpythonコードを示す。
import cv2 import numpy as np from matplotlib import pyplot as plt from google.colab import files uploaded_file = files.upload() uploaded_file_name = next(iter(uploaded_file)) orig = cv2.imread(uploaded_file_name)
Google Colabにアップロードした画像(BGR)をグレースケールに変換して表示する。
gray = cv2.cvtColor(orig, cv2.COLOR_BGR2GRAY)
plt.imshow(gray,cmap='gray')
次にグレースケールの元画像に閾値と閾値を越えたピクセル値に白(255)を割り当てるにはcv2.threshold(src,threshold,maxval,method)
を用いる。srcは元画像、thresholdは閾値、maxvalは閾値超えたピクセルに割り当てる値で白であれば255,methodは2値化の方法を指定することができる。以下のコードではthreshold=127, maxval=255(白), method=cv2.THRESH_BINRYと白黒を反転させる method=cv2.THRESH_BINRY_INVを指定した。
なおplt.imshow()
でvmin = 0, vmax = 255
を入れないと自動的に表示スケールが最適化されてしまう。
ret,thresh1 = cv2.threshold(gray,127,255,cv2.THRESH_BINARY) ret,thresh2 = cv2.threshold(gray,127,255,cv2.THRESH_BINARY_INV) plt.figure(figsize=(10,20)) plt.subplot(1,2,1) plt.imshow(thresh1,cmap='gray',vmin = 0, vmax = 255) plt.subplot(1,2,2) plt.imshow(thresh2,cmap='gray',vmin = 0, vmax = 255)
左が元画像を2値化処理したもの、右は反転させた画像になる。
2. その他の2値化処理
単純な2値化処理でmaxval=255の代わりに、maxval=100とすると白の代わりにグレースケールが閾値を越えるピクセルに割り当てられる。左がmaxval=255,右がmaxval=100の画像。
methodとして,cv2.THRESH_BINARY
やcv2.THRESH_BINARY_INV
以外で2値化処理するコードと画像を以下に示す。
ret,thresh3 = cv2.threshold(gray,127,255,cv2.THRESH_TRUNC) ret,thresh4 = cv2.threshold(gray,127,255,cv2.THRESH_TOZERO) ret,thresh5 = cv2.threshold(gray,127,255,cv2.THRESH_TOZERO_INV) plt.figure(figsize=(8,8)) plt.subplot(2,2,1) plt.imshow(thresh3,cmap='gray',vmin = 0, vmax = 255) plt.subplot(2,2,3) plt.imshow(thresh4,cmap='gray',vmin = 0, vmax = 255) plt.subplot(2,2,4) plt.imshow(thresh5,cmap='gray',vmin = 0, vmax = 255)
上段がcv2.THRESH_TRUNC
で下段がcv2.THRESH_TOZERO
、下段左が反転させたcv2.THRESH_TOZERO_INV
を適用した画像になる。
それぞれの詳細は以下のドキュメントを参照。
Miscellaneous Image Transformations — OpenCV 3.0.0-dev documentation
3. 適応的2値化処理
上では閾値を設定して画像全体に適用していたが、全体の照明の当たり方など画像の明るさが一様でないときに画像中の小領域ごとに閾値を計算して適用する。
適用的2値化処理を実行するにはcv2.adaptiveThreshold(src,maxval,thresh_method,method,blocksize,constant)
を用いる。src, maxval,methodはcv2.threshold
と同じ意味、thresh_methodは閾値を計算する方法、blocksizeは閾値を計算する小領域のサイズ(奇数), constantは計算された閾値から減算する定数。小領域のサイズを11, 2値化処理方法をcv2.THRESH_BINARY
, thresh_methodをcv2.ADAPTIVE_THRESH_MEAN_C
とcv2.ADAPTIVE_THRESH_GAUSSIAN_C
とする場合のpythonコードを以下に示す。
ath1 = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,11,2) ath2 = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11,2) plt.figure(figsize=(10,20)) plt.subplot(1,2,1) plt.imshow(ath1,cmap='gray',,vmin = 0, vmax = 255) plt.subplot(1,2,2) plt.imshow(ath2,cmap='gray',,vmin = 0, vmax = 255)
実行すると以下のような画像(左がADAPTIVE_THRESH_MEAN_C,右がADAPTIVE_THRESH_GAUSSIAN_C)になり、輪郭を抽出するのに特に向いている
4. まとめ
今回はOpenCVを画像のいろいろな2値化処理方法について紹介した。2値化処理は画像マスクや輪郭を抽出する上で有用に使用することができる。