OpenCV 画像の閾値処理
画像処理において、閾値処理は画像を二値画像(白黒画像)に変換するための一般的な技術です。閾値を設定することで、画像内のピクセルを閾値より高いピクセルと低いピクセルの2つのクラスに分類できます。
OpenCV はさまざまな閾値処理方法を提供しています。この記事では、単純閾値処理、適応的閾値処理、大津の二値化という3つの一般的な閾値処理技術を詳しく紹介します。
1. 単純閾値処理 (cv2.threshold())
単純閾値処理は最も基本的な閾値処理方法です。固定の閾値を設定することで、画像内のピクセルを2つのクラスに分類します。
OpenCV は提供していますcv2.threshold()関数を使用してこの機能を実現します。
関数プロトタイプ
retval, dst = cv2.threshold(src, thresh, maxval, type)
パラメータの説明
src: 入力画像。通常はグレースケール画像です。thresh: 設定する閾値。maxval: ピクセル値が閾値を超えた場合(または種類によっては下回った場合)に割り当てる新しい値。type: 閾値処理のタイプ。一般的なタイプは次のとおりです。cv2.THRESH_BINARY: ピクセル値が閾値より大きい場合は、割り当てますmaxval、そうでない場合は割り当てます0。cv2.THRESH_BINARY_INV: ~とはcv2.THRESH_BINARY逆に、ピクセル値が閾値より大きい場合は、割り当てます0、そうでない場合は割り当てますmaxval。cv2.THRESH_TRUNC: ピクセル値が閾値より大きい場合は、閾値を割り当て、それ以外の場合は値を変更しません。cv2.THRESH_TOZERO: ピクセル値が閾値より大きい場合は、値を変更せず、それ以外の場合は割り当てます0。cv2.THRESH_TOZERO_INV: ~とはcv2.THRESH_TOZERO逆に、ピクセル値が閾値より大きい場合は、割り当てます0、それ以外の場合は値を変更しません。
戻り値
retval: 実際に使用された閾値(場合によっては設定した閾値と異なることがあります)。dst: 処理後の画像。
例
例
import cv2
import numpy as np
# 画像を読み込む
img = cv2.imread('image.jpg', 0)
# 単純閾値処理
ret, thresh1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
# 結果を表示する
cv2.imshow('Binary Threshold', thresh1)
cv2.waitKey(0)
cv2.destroyAllWindows()
import numpy as np
# 画像を読み込む
img = cv2.imread('image.jpg', 0)
# 単純閾値処理
ret, thresh1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
# 結果を表示する
cv2.imshow('Binary Threshold', thresh1)
cv2.waitKey(0)
cv2.destroyAllWindows()
2. 適応的閾値処理 (cv2.adaptiveThreshold())
場合によっては、画像の明るさの分布が不均一なため、固定の閾値では理想的な結果が得られないことがあります。適応的閾値処理は、画像の領域ごとに異なる閾値を計算することで、このような状況にうまく対応します。
関数プロトタイプ
dst = cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C)
パラメータの説明
src: 入力画像。通常はグレースケール画像です。maxValue: ピクセル値が閾値を超えた場合(または種類によっては下回った場合)に割り当てる新しい値。adaptiveMethod: 適応的閾値の計算方法。一般的なタイプは次のとおりです。cv2.ADAPTIVE_THRESH_MEAN_C: 閾値は近傍の平均値から定数を差し引いた値です。C。cv2.ADAPTIVE_THRESH_GAUSSIAN_C: 閾値は近傍の加重平均値から定数を差し引いた値です。C、重みはガウス関数によって決定されます。
thresholdType: 閾値処理のタイプ。通常はcv2.THRESH_BINARY或cv2.THRESH_BINARY_INV。blockSize: 閾値計算に使用する近傍のサイズ。奇数である必要があります。C: 平均値または加重平均値から差し引く定数。
戻り値
dst: 処理後の画像。
例
例
import cv2
import numpy as np
# 画像を読み込む
img = cv2.imread('image.jpg', 0)
# 適応的閾値処理
thresh2 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2)
# 結果を表示する
cv2.imshow('Adaptive Threshold', thresh2)
cv2.waitKey(0)
cv2.destroyAllWindows()
import numpy as np
# 画像を読み込む
img = cv2.imread('image.jpg', 0)
# 適応的閾値処理
thresh2 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2)
# 結果を表示する
cv2.imshow('Adaptive Threshold', thresh2)
cv2.waitKey(0)
cv2.destroyAllWindows()
3. 大津の二値化 (cv2.threshold() with cv2.THRESH_OTSU)
大津の二値化は、閾値を自動的に決定する方法です。クラス間分散を最大化することで最適な大域閾値を見つけ、二峰性の画像(つまり画像ヒストグラムに明確なピークが2つある画像)に適しています。
関数プロトタイプ
retval, dst = cv2.threshold(src, thresh, maxval, type)
パラメータの説明
src: 入力画像。通常はグレースケール画像です。thresh大津の方法では閾値が自動的に決定されるため、このパラメータは通常設定されます。0。maxval: ピクセル値が閾値を超えた場合(または種類によっては下回った場合)に割り当てる新しい値。type: 閾値処理のタイプ。通常はcv2.THRESH_BINARY或cv2.THRESH_BINARY_INV、さらにcv2.THRESH_OTSU。
戻り値
retval: 自動的に決定された閾値。dst: 処理後の画像。
例
例
import cv2
import numpy as np
# 画像を読み込む
img = cv2.imread('image.jpg', 0)
# 大津の二値化
ret, thresh3 = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# 結果を表示する
cv2.imshow('Otsu\'s Threshold', thresh3)
cv2.waitKey(0)
cv2.destroyAllWindows()
import numpy as np
# 画像を読み込む
img = cv2.imread('image.jpg', 0)
# 大津の二値化
ret, thresh3 = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# 結果を表示する
cv2.imshow('Otsu\'s Threshold', thresh3)
cv2.waitKey(0)
cv2.destroyAllWindows()