scikit-image における Thresholdingについて
おはこんばんちは!
早速ですが、みなさんはscikit-image使っていますか?
画像処理を行うとなると、どうしてもOpenCV一強になりがちですが、
実はscikit-imageも特徴量や認識に関するライブラリが多数あるので、ぜひ活用してみてください。
その中でも今回は、閾値処理に焦点を当てていきたいと思います。
scikit-imageの閾値処理は10個の手法が用意されています。
(Module: filters — skimage v0.15.dev0 docs)
- Otsu
- Yen
(最大相関値に基づいた二値化)
- Isodata
- Local
- Li
(元画像と2値化画像間の交差エントロピーが最小となるように,2値化値を選択する)
- Minimum
(入力画像のヒストグラムは、2つの最大値が得られるまで計算され、平滑化される。 そのときの最小値が閾値となる)
- Mean
(グレースケール値の平均に基づいて閾値を計算する)
- Niblack
- Sauvola
- Triangle
メジャーなものからマイナーなものまで用意されていますが、何を使ったらいいかわからない人におすすめなのが try_all_threshold です。
これは、先ほどの閾値手法のうち、
- Isodata
- Li
- Mean
- Minimum
- Otsu
- Triangle
- Yen
の処理をまとめておこない、結果を見ることができるメソッドです。
from skimage.filters import try_all_threshold from skimage import io img = io.imread('lena.png',True)#read grayScale fig, ax = try_all_threshold(img, figsize=(10,8), verbose=False)
個別に行いたい場合は、
from skimage import io import matplotlib.pyplot as plt from skimage.filters import threshold_isodata img = io.imread('lena.png',True) isodata_thresh =threshold_isodata(img)#Return thresh binary = img > isodata_thresh plt.imshow(binary,cmap=plt.cm.gray)
これらの処理は閾値を値として返すので、それらをヒストグラムにプロットしてあげると
from skimage import io import matplotlib.pyplot as plt from skimage.filters import threshold_isodata from skimage.filters import threshold_minimum from skimage.filters import threshold_yen img = io.imread('lena.png',True) isodata_thresh =threshold_isodata(img)#isodata method minimum_thresh =threshold_minimum(img)#minimum method yen_thresh =threshold_yen(img)#minimum method plt.hist(img.ravel()*255,range(0,255)) plt.axvline(x=isodata_thresh*255,c='r',label="isodata") plt.axvline(x=minimum_thresh*255,c='k',label="minimum") plt.axvline(x=yen_thresh*255,c='b',label="yen") plt.legend()
閾値手法の比較が行えますね。