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()

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()

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()
その他の拡張