この記事のゴールはクラスタリングによる画像分割アルゴリズムを体験することです.対象はcamera manにしましょう.
(全てipython --pylab上で動かします.)
from skimage import data,io
image=data.camera()
io.imshow(image)
クラスタリング対象は各ピクセルです.データ数n,次元数dとしたとき,クラスタリングアルゴリズムを使うには,n×d行列を作らないといけません.今回対象は各ピクセルなのでn=512×512=262144, d=1の262144×1行列をまず作ります.
X=image.reshape((-1,1))
これで準備完了です.クラスタリングしましょう.Mean-Shiftクラスタリングを使います.Mean-Shiftクラスタリングはクラスタ数を事前に決める必要がないことから,画像分割に適していると考えられています.こいつはすでにscikit-learnで実装されています.なんて便利なんだろう....いくつかパラメータがありますが,参考文献に忠実にやってみます.
from sklearn.cluster import MeanShift,estimate_bandwidth
bandwidth=estimate_bandwidth(X,quantile=0.2,n_samples=500)
ms=MeanShift(bandwidth=bandwidth,bin_seeding=True)
ms.fit(X)
これでクラスタリング完了です.結果を見てみましょう.
segmented_image=ms.labels_
segmented_image.shape=image.shape
imshow(segmented_image)
#matshow(segmented_image)
クラスタ数も見てみます.
print len(unique(ms.labels_))
3
camera manは3つの部分に分割されました.これがいいのか悪いのかを評価するには正解データが必要ですが,どこかにあるのでしょうか?
Mean-Shiftクラスタリングの性能はbandwidthに大きく依存します.今回はsklearnにbandwidthを推定する関数があったので使ってみましたが,中で何をやっているのか見ていませんのでなんとも言えません.とりあえずscikitシリーズを使って画像分割を体験できたのでよしとします.
ありがとうございました.