画像分割のためのスペクトラルクラスタリング

Machine LearningMachine LearningBeginner
今すぐ練習

This tutorial is from open-source community. Access the source code

💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください

はじめに

この実験では、スペクトラルクラスタリングを使用して画像分割を行う方法を学びます。複数の連結した円がある画像を生成し、スペクトラルクラスタリングを使って円を分離します。

VMのヒント

VMの起動が完了したら、左上隅をクリックしてノートブックタブに切り替え、Jupyter Notebookを使って練習しましょう。

Jupyter Notebookが読み込み終わるまで数秒待つことがあります。Jupyter Notebookの制限により、操作の検証は自動化できません。

学習中に問題がある場合は、Labbyにお問い合わせください。セッション後にフィードバックを提供してください。すぐに問題を解決いたします。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL ml(("Machine Learning")) -.-> ml/FrameworkandSoftwareGroup(["Framework and Software"]) sklearn(("Sklearn")) -.-> sklearn/CoreModelsandAlgorithmsGroup(["Core Models and Algorithms"]) sklearn(("Sklearn")) -.-> sklearn/DataPreprocessingandFeatureEngineeringGroup(["Data Preprocessing and Feature Engineering"]) sklearn/CoreModelsandAlgorithmsGroup -.-> sklearn/cluster("Clustering") sklearn/DataPreprocessingandFeatureEngineeringGroup -.-> sklearn/feature_extraction("Feature Extraction") ml/FrameworkandSoftwareGroup -.-> ml/sklearn("scikit-learn") subgraph Lab Skills sklearn/cluster -.-> lab-49278{{"画像分割のためのスペクトラルクラスタリング"}} sklearn/feature_extraction -.-> lab-49278{{"画像分割のためのスペクトラルクラスタリング"}} ml/sklearn -.-> lab-49278{{"画像分割のためのスペクトラルクラスタリング"}} end

データの生成

numpyを使って4つの円がある画像を生成します。その後、画像にノイズを追加し、画像を前景に限定するマスクを作成します。

import numpy as np

l = 100
x, y = np.indices((l, l))

center1 = (28, 24)
center2 = (40, 50)
center3 = (67, 58)
center4 = (24, 70)

radius1, radius2, radius3, radius4 = 16, 14, 15, 14

circle1 = (x - center1[0]) ** 2 + (y - center1[1]) ** 2 < radius1**2
circle2 = (x - center2[0]) ** 2 + (y - center2[1]) ** 2 < radius2**2
circle3 = (x - center3[0]) ** 2 + (y - center3[1]) ** 2 < radius3**2
circle4 = (x - center4[0]) ** 2 + (y - center4[1]) ** 2 < radius4**2

img = circle1 + circle2 + circle3 + circle4

mask = img.astype(bool)

img = img.astype(float)
img += 1 + 0.2 * np.random.randn(*img.shape)

画像をグラフに変換する

画像をグラフに変換するために、sklearn.feature_extraction.imageimg_to_graph を使います。辺の勾配の値も計算されます。

from sklearn.feature_extraction import image

graph = image.img_to_graph(img, mask=mask)

スペクトラルクラスタリング

sklearn.clusterspectral_clustering 関数を使って、スペクトラルクラスタリングを行います。4つの円を分離するために、n_clusters パラメータを4に設定します。

from sklearn.cluster import spectral_clustering

labels = spectral_clustering(graph, n_clusters=4, eigen_solver="arpack")

結果をプロットする

matplotlib.pyplotmatshow を使って、元の画像と分割された画像を横並びにプロットします。

import matplotlib.pyplot as plt

label_im = np.full(mask.shape, -1.0)
label_im[mask] = labels

fig, axs = plt.subplots(nrows=1, ncols=2, figsize=(10, 5))
axs[0].matshow(img)
axs[1].matshow(label_im)

plt.show()

2つの円をプロットする

上記のプロセスを繰り返しますが、生成された最初の2つの円のみを考慮します。

img = circle1 + circle2
mask = img.astype(bool)
img = img.astype(float)

img += 1 + 0.2 * np.random.randn(*img.shape)

graph = image.img_to_graph(img, mask=mask)
graph.data = np.exp(-graph.data / graph.data.std())

labels = spectral_clustering(graph, n_clusters=2, eigen_solver="arpack")
label_im = np.full(mask.shape, -1.0)
label_im[mask] = labels

fig, axs = plt.subplots(nrows=1, ncols=2, figsize=(10, 5))
axs[0].matshow(img)
axs[1].matshow(label_im)

plt.show()

まとめ

この実験では、スペクトラルクラスタリングを使って画像分割を行う方法を学びました。複数の連結した円がある画像を生成し、画像をグラフに変換し、スペクトラルクラスタリングを行い、結果をプロットしました。