はじめに
この実験では、階層的クラスタリングを使って 2 次元画像をセグメント化する方法を学びます。階層的クラスタリングは、似たようなデータポイントをグループ化するクラスタリングアルゴリズムです。画像セグメント化の文脈では、階層的クラスタリングは、似たような色の強度を持つ画素をグループ化するために使用でき、画像内の明確な領域や物体を識別するのに役立ちます。
私たちは、Python の scikit-learn ライブラリを使って、コインの画像に対して階層的クラスタリングを行います。
VM のヒント
VM の起動が完了したら、左上隅をクリックしてノートブックタブに切り替えて、Jupyter Notebook を使って練習しましょう。
時々、Jupyter Notebook が読み込み終わるまで数秒待つ必要があります。Jupyter Notebook の制限により、操作の検証は自動化できません。
学習中に問題に直面した場合は、Labby にお尋ねください。セッション後にフィードバックを提供してください。私たちは迅速に問題を解決いたします。
データの生成
まずはデータを生成します。scikit-image のcoinsデータセットを使います。これはコインの 2 次元グレースケール画像です。処理を高速化するために、画像を元のサイズの 20% にリサイズします。
from skimage.data import coins
import numpy as np
from scipy.ndimage import gaussian_filter
from skimage.transform import rescale
orig_coins = coins()
## Resize it to 20% of the original size to speed up the processing
## Applying a Gaussian filter for smoothing prior to down-scaling
## reduces aliasing artifacts.
smoothened_coins = gaussian_filter(orig_coins, sigma=2)
rescaled_coins = rescale(
smoothened_coins,
0.2,
mode="reflect",
anti_aliasing=False,
)
X = np.reshape(rescaled_coins, (-1, 1))
データの構造を定義する
画像内の画素はその近傍の画素と接続されています。画像に対して階層的クラスタリングを行うためには、データの構造を定義する必要があります。データの構造を定義する接続行列を作成するために、scikit-learn のgrid_to_graph関数を使うことができます。
from sklearn.feature_extraction.image import grid_to_graph
connectivity = grid_to_graph(*rescaled_coins.shape)
クラスタリングの計算
データと接続行列が定義されたので、これで階層的クラスタリングを行うことができます。階層的クラスタリングを行うために、scikit-learn のAgglomerativeClusteringクラスを使います。クラスタの数を 27 に設定します。これは画像内のコインの数です。マージされるクラスタ間の距離の分散を最小化する「ward」リンク法を使います。また、手順 2 で作成した接続行列も渡します。
from sklearn.cluster import AgglomerativeClustering
import time as time
print("Compute structured hierarchical clustering...")
st = time.time()
n_clusters = 27 ## number of regions
ward = AgglomerativeClustering(
n_clusters=n_clusters, linkage="ward", connectivity=connectivity
)
ward.fit(X)
label = np.reshape(ward.labels_, rescaled_coins.shape)
print(f"Elapsed time: {time.time() - st:.3f}s")
print(f"Number of pixels: {label.size}")
print(f"Number of clusters: {np.unique(label).size}")
結果をプロットする
最後に、画像上に結果をプロットすることができます。リサイズされた画像とクラスタの輪郭をプロットするために matplotlib を使います。各クラスタをループして、そのクラスタ内の画素の輪郭をプロットします。
import matplotlib.pyplot as plt
plt.figure(figsize=(5, 5))
plt.imshow(rescaled_coins, cmap=plt.cm.gray)
for l in range(n_clusters):
plt.contour(
label == l,
colors=[
plt.cm.nipy_spectral(l / float(n_clusters)),
],
)
plt.axis("off")
plt.show()
まとめ
この実験では、2 次元画像をセグメント化するために階層的クラスタリングをどのように使用するかを学びました。データを生成し、データの構造を定義し、階層的クラスタリングを行い、画像上に結果をプロットしました。この技術は、画像内の明確な領域や物体を識別する際に役立つ場合があります。