EX 12: Spectral clustering for image segmentation
此範例是利用Spectral clustering來區別重疊的圓圈,將重疊的圓圈分為個體。
    1.
    建立一個100x100的影像包含四個不同半徑的圓
    2.
    透過np.indices改變影像顏色複雜度
    3.
    spectral_clustering區分出各個不同區域特徵

(一)引入函式庫

引入函式庫如下: 1. numpy:產生陣列數值 2. matplotlib.pyplot:用來繪製影像 3. sklearn.feature_extraction import image:將每個像素的梯度關係圖像化 4. sklearn.cluster import spectral_clustering:將影像正規化切割
1
import numpy as np
2
import matplotlib.pyplot as plt
3
4
from sklearn.feature_extraction import image
5
from sklearn.cluster import spectral_clustering
Copied!

(二)建立要被區分的重疊圓圈影像

    產生一個大小為輸入值得矩陣(此範例為100x100),其內部值為沿著座標方向遞增(如:0,1,...)的值。
1
l = 100
2
x, y = np.indices((l, l))
Copied!
    建立四個圓圈的圓心座標並給定座標值
    給定四個圓圈的半徑長度
    將圓心座標與半徑結合產生四個圓圈圖像
1
center1 = (28, 24)
2
center2 = (40, 50)
3
center3 = (67, 58)
4
center4 = (24, 70)
5
6
radius1, radius2, radius3, radius4 = 16, 14, 15, 14
7
8
circle1 = (x - center1[0]) ** 2 + (y - center1[1]) ** 2 < radius1 ** 2
9
circle2 = (x - center2[0]) ** 2 + (y - center2[1]) ** 2 < radius2 ** 2
10
circle3 = (x - center3[0]) ** 2 + (y - center3[1]) ** 2 < radius3 ** 2
11
circle4 = (x - center4[0]) ** 2 + (y - center4[1]) ** 2 < radius4 ** 2
Copied!
    將上一段產生的四個圓圈影像合併為img使其成為一體的物件
    mask為布林形式的img
    img為浮點數形式的img
    用亂數產生的方法將整張影像作亂數處理
1
# 4 circles
2
img = circle1 + circle2 + circle3 + circle4
3
mask = img.astype(bool)
4
img = img.astype(float)
5
6
img += 1 + 0.2 * np.random.randn(*img.shape)
Copied!
接著將產生好的影像化為可使用spectral_clustering的影像
    image.img_to_graph 用來處理邊緣的權重與每個像速間的梯度關聯有關
    用類似Voronoi Diagram演算法的概念來處理影像
1
graph = image.img_to_graph(img, mask=mask)
2
3
graph.data = np.exp(-graph.data / graph.data.std())
Copied!
最後用spectral_clustering將連在一起的部分切開,而spectral_clustering中的各項參數設定如下:
    graph: 必須是一個矩陣且大小為nxn的形式
    n_clusters=4: 需要提取出的群集數
    eigen_solver='arpack': 解特徵值的方式
開一張新影像label_im用來展示spectral_clustering切開後的分類結果
1
labels = spectral_clustering(graph, n_clusters=4, eigen_solver='arpack')
2
label_im = -np.ones(mask.shape)
3
label_im[mask] = labels
4
5
plt.matshow(img)
6
plt.matshow(label_im)
Copied!

(三)完整程式碼

Python source code:plot_segmentation_toy.py
1
print(__doc__)
2
3
# Authors: Emmanuelle Gouillart <[email protected]>
4
# Gael Varoquaux <[email protected]>
5
# License: BSD 3 clause
6
7
import numpy as np
8
import matplotlib.pyplot as plt
9
10
from sklearn.feature_extraction import image
11
from sklearn.cluster import spectral_clustering
12
13
###############################################################################
14
l = 100
15
x, y = np.indices((l, l))
16
17
center1 = (28, 24)
18
center2 = (40, 50)
19
center3 = (67, 58)
20
center4 = (24, 70)
21
22
radius1, radius2, radius3, radius4 = 16, 14, 15, 14
23
24
circle1 = (x - center1[0]) ** 2 + (y - center1[1]) ** 2 < radius1 ** 2
25
circle2 = (x - center2[0]) ** 2 + (y - center2[1]) ** 2 < radius2 ** 2
26
circle3 = (x - center3[0]) ** 2 + (y - center3[1]) ** 2 < radius3 ** 2
27
circle4 = (x - center4[0]) ** 2 + (y - center4[1]) ** 2 < radius4 ** 2
28
29
###############################################################################
30
# 4 circles
31
img = circle1 + circle2 + circle3 + circle4
32
mask = img.astype(bool)
33
img = img.astype(float)
34
35
img += 1 + 0.2 * np.random.randn(*img.shape)
36
37
# Convert the image into a graph with the value of the gradient on the
38
# edges.
39
graph = image.img_to_graph(img, mask=mask)
40
41
# Take a decreasing function of the gradient: we take it weakly
42
# dependent from the gradient the segmentation is close to a voronoi
43
graph.data = np.exp(-graph.data / graph.data.std())
44
45
# Force the solver to be arpack, since amg is numerically
46
# unstable on this example
47
labels = spectral_clustering(graph, n_clusters=4, eigen_solver='arpack')
48
label_im = -np.ones(mask.shape)
49
label_im[mask] = labels
50
51
plt.matshow(img)
52
plt.matshow(label_im)
53
54
###############################################################################
55
# 2 circles
56
img = circle1 + circle2
57
mask = img.astype(bool)
58
img = img.astype(float)
59
60
img += 1 + 0.2 * np.random.randn(*img.shape)
61
62
graph = image.img_to_graph(img, mask=mask)
63
graph.data = np.exp(-graph.data / graph.data.std())
64
65
labels = spectral_clustering(graph, n_clusters=2, eigen_solver='arpack')
66
label_im = -np.ones(mask.shape)
67
label_im[mask] = labels
68
69
plt.matshow(img)
70
plt.matshow(label_im)
71
72
plt.show()
Copied!