OpenCVの使用方法について、前回の画像の2値化処理の続きで大津の2値化について紹介したい。
1. 大津の2値化
前回の画像の2値化処理で閾値を自動計算する方法として小区間にわけて閾値を計算する適用的2値化について紹介したが、画像全体閾値の自動計算として画像輝度値のヒストグラムから2つのクラスに分ける閾値を算出する大津の2値化が知られている。(詳細は2値化(大津の2値化) | 画像認識の技術ブログ | マクセルフロンティア株式会社など参照)
以下の画像(gray
)を大津の2値化を用いて閾値を自動計算して2値処理する例を示す。
サンプル画像までのコードは下を展開。
サンプル画像読み込み
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) gray = cv2.cvtColor(orig, cv2.COLOR_BGR2GRAY) plt.imshow(gray,cmap='gray')
2. 大津の2値化の適用
大津の2値化を適用して閾値を設定するには、cv2.threshold()
のthreshold=0として、method=cv2.THRESH_BINARY+cv2.THRESH_OTSU
とする。なお2値化処理方法を別の方法にするにはmethod=cv2.THRESH_TRUNC+cv2.THRESH_OTSU
などすればよい。
ret3,ath3 = cv2.threshold(gray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU) plt.figure(figsize=(10,20)) plt.subplot(1,2,1) plt.imshow(thresh1,cmap='gray',,vmin = 0, vmax = 255) plt.title('THRESH_BINARY') plt.subplot(1,2,2) plt.imshow(ath3,cmap='gray',,vmin = 0, vmax = 255) plt.title('BINARY+THRESH_OTSU')
左の画像はthreshold=127とした場合、右は大津の2値化で閾値を自動計算した画像になる。自動計算された閾値はret3
に格納されており、下の画像の場合は102になっている。
閾値を127に設定した場合よりも、大津の2値化で求めた閾値の方が白黒のバランスがよい感じがする。
2値化処理をBINARY_TRUNC
にした場合の比較(左:threshold=127,右:大津の2値化)する。
ret4,ath4 = cv2.threshold(gray,0,255,cv2.THRESH_TRUNC+cv2.THRESH_OTSU) plt.figure(figsize=(10,20)) plt.subplot(1,2,1) plt.imshow(thresh3,cmap='gray',,vmin = 0, vmax = 255) plt.title('THRESH_TRUNC') plt.subplot(1,2,2) plt.imshow(ath4,cmap='gray',,vmin = 0, vmax = 255) plt.title('TRUNC+THRESH_OTSU')
ここで元画像gray
の輝度ヒストグラムと大津の2値化で得られた閾値を赤線で示す。画像の輝度ヒストグラムはgray.ravel()
として2次元マトリックスを1次元に変換してからplt.hist(
gray.ravel(),256)`を適用する。256は値の区切り数で、画像データは0~255のため256とした。元画像は低輝度側に多く分布していて、高い輝度ほど頻度が減っていることがわかる。
a=plt.hist(gray.ravel(),256) plt.xlabel('Value') plt.ylabel('Count') plt.title('Peach') plt.vlines(102, 0, 3000, "red")
3. 他の画像への適用例
大津の2値化を用いて、代表的な標準画像(例えば標準画像データベース[神奈川工大 信号処理応用研究室])に対して2値化処理と輝度分布の関係を調べてみた。基本的にはカラー画像をグレースケール変換したものを元画像としている。OpenCVのコードは上のコードと同じ
マンドリルの輝度ヒストグラムは120付近に大きなピークと170付近に小さなピークがあり、閾値としては130付近に設定されている。2値化処理した画像としては綺麗に分けられている。
オウムの輝度ヒストグラムは90付近の大きなピークと190付近にピークがあり、閾値としては140付近に設定されている。2値化処理した画像は、色合いとしては分けられているが画像としては左側のインコが識別しにくい。
唐辛子の輝度ヒストグラムは90付近のピークと160~180付近のピークに大別でき、閾値としては120付近に設定されている。2つの画像の色(カラーでは緑と赤)がしっかりとわけられている。