EX 6: 以群聚法切割錢幣影像.md
此範例用Spectral Clustering以分割圖中的硬幣
    1.
    利用coins()匯入圖片
    2.
    利用spectral_clustering做切割
    3.
    最後將結果可視化

(一)引入函式庫

引入函式如下:
    1.
    time : 提供各種與時間相關函數
    2.
    numpy : 產生陣列數值
    3.
    scipy.ndimage.filters import gaussian_filter : 做gaussian filter
    4.
    matplotlib.pyplot : 用來繪製影像
    5.
    skimage.data import coins : 匯入龐貝城的希臘硬幣
    6.
    skimage.transform import rescale : 用來縮放圖片
    7.
    sklearn.feature_extraction import image : 將每個像素的梯度關係圖像化
    8.
    sklearn.cluster import spectral_clustering : 將影像正規化切割
1
import time
2
import numpy as np
3
from scipy.ndimage.filters import gaussian_filter
4
import matplotlib.pyplot as plt
5
from skimage.data import coins
6
from skimage.transform import rescale
7
8
from sklearn.feature_extraction import image
9
from sklearn.cluster import spectral_clustering
10
11
orig_coins = coins()
12
13
smoothened_coins = gaussian_filter(orig_coins, sigma=2)
14
rescaled_coins = rescale(smoothened_coins, 0.2, mode="reflect")
Copied!
coins() : 匯入一張303x384的影像 用 rescale 將圖片 resize 成原圖的20%(61x77)來加快處理,並根據 mode 選擇 padding 方式

(二)Clustering

1
# Convert the image into a graph with the value of the gradient on the edges.
2
graph = image.img_to_graph(rescaled_coins)
Copied!
img_to_graph : 用來處理邊緣的權重與每個像速間的梯度關聯
1
beta = 10
2
eps = 1e-6
3
graph.data = np.exp(-beta * graph.data / graph.data.std()) + eps
Copied!
beta越小,實際圖像會分割的越獨立,當 beta = 1 時,會類似Voronoi Diagram演算法的概念
1
N_REGIONS = 24
2
3
for assign_labels in ('kmeans', 'discretize'):
4
t0 = time.time()
5
labels = spectral_clustering(graph, n_clusters=N_REGIONS,
6
assign_labels=assign_labels, random_state=42)
7
t1 = time.time()
8
labels = labels.reshape(rescaled_coins.shape)
9
10
plt.figure(figsize=(5, 5))
11
plt.imshow(rescaled_coins, cmap=plt.cm.gray)
12
for l in range(N_REGIONS):
13
plt.contour(labels == l,
14
colors=[plt.cm.nipy_spectral(l / float(N_REGIONS))])
15
plt.xticks(())
16
plt.yticks(())
17
title = 'Spectral clustering: %s, %.2fs' % (assign_labels, (t1 - t0))
18
print(title)
19
plt.title(title)
20
plt.show()
Copied!
用spectral_clustering將連在一起的部分切開,而spectral_clustering中的各項參數設定如下:
    graph: 必須是一個矩陣且大小為nxn的形式
    n_clusters: 需要提取出的群集數
    random_state: 偽隨機數產生器,用於初始化特徵向量分解計算
    assign_labels:選擇assign label的方法(kmeans or discretize)
用plt.contour畫出等高線,同個label會被框在同個圈內

(三)完整程式碼

Python source code:plot_coin_segmentation.py
1
"""
2
================================================
3
Segmenting the picture of greek coins in regions
4
================================================
5
6
This example uses :ref:`spectral_clustering` on a graph created from
7
voxel-to-voxel difference on an image to break this image into multiple
8
partly-homogeneous regions.
9
10
This procedure (spectral clustering on an image) is an efficient
11
approximate solution for finding normalized graph cuts.
12
13
There are two options to assign labels:
14
15
* with 'kmeans' spectral clustering will cluster samples in the embedding space
16
using a kmeans algorithm
17
* whereas 'discrete' will iteratively search for the closest partition
18
space to the embedding space.
19
"""
20
print(__doc__)
21
22
# Author: Gael Varoquaux <[email protected]>, Brian Cheung
23
# License: BSD 3 clause
24
25
import time
26
27
import numpy as np
28
from scipy.ndimage.filters import gaussian_filter
29
import matplotlib.pyplot as plt
30
from skimage.data import coins
31
from skimage.transform import rescale
32
33
from sklearn.feature_extraction import image
34
from sklearn.cluster import spectral_clustering
35
36
37
# load the coins as a numpy array
38
orig_coins = coins()
39
40
# Resize it to 20% of the original size to speed up the processing
41
# Applying a Gaussian filter for smoothing prior to down-scaling
42
# reduces aliasing artifacts.
43
smoothened_coins = gaussian_filter(orig_coins, sigma=2)
44
rescaled_coins = rescale(smoothened_coins, 0.2, mode="reflect")
45
46
# Convert the image into a graph with the value of the gradient on the
47
# edges.
48
graph = image.img_to_graph(rescaled_coins)
49
50
# Take a decreasing function of the gradient: an exponential
51
# The smaller beta is, the more independent the segmentation is of the
52
# actual image. For beta=1, the segmentation is close to a voronoi
53
beta = 10
54
eps = 1e-6
55
graph.data = np.exp(-beta * graph.data / graph.data.std()) + eps
56
57
# Apply spectral clustering (this step goes much faster if you have pyamg
58
# installed)
59
N_REGIONS = 24
60
61
#############################################################################
62
# Visualize the resulting regions
63
64
for assign_labels in ('kmeans', 'discretize'):
65
t0 = time.time()
66
labels = spectral_clustering(graph, n_clusters=N_REGIONS,
67
assign_labels=assign_labels, random_state=42)
68
t1 = time.time()
69
labels = labels.reshape(rescaled_coins.shape)
70
71
plt.figure(figsize=(5, 5))
72
plt.imshow(rescaled_coins, cmap=plt.cm.gray)
73
for l in range(N_REGIONS):
74
plt.contour(labels == l,
75
colors=[plt.cm.nipy_spectral(l / float(N_REGIONS))])
76
plt.xticks(())
77
plt.yticks(())
78
title = 'Spectral clustering: %s, %.2fs' % (assign_labels, (t1 - t0))
79
print(title)
80
plt.title(title)
81
plt.show()
Copied!