层次聚类是一种常用的聚类算法,它可以将数据点分组成不同的簇,并且每个簇内的点在空间上是相互连接的。在图像处理领域,层次聚类可以用于图像分割,将图像中的像素点根据相似性分组,以识别出图像中的不同对象。本文将介绍如何使用Ward方法进行层次聚类,并展示其在二维图像分割中的应用。
首先,需要生成或获取一张二维图像数据。在本例中,使用Python的skimage.data
模块中的coins
函数来生成一张硬币图像。为了加快处理速度,将图像缩小到原始大小的20%,并在缩小前应用高斯滤波器进行平滑处理,以减少混叠效应。
from skimage.data import coins
orig_coins = coins()
import numpy as np
from scipy.ndimage import gaussian_filter
from skimage.transform import rescale
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))
上述代码首先加载了硬币图像,然后使用高斯滤波器对其进行平滑处理,最后将图像缩小到原大小的20%,并将图像数据转换为一维数组,以便于后续的聚类处理。
在层次聚类中,需要定义数据点之间的连接关系。在图像中,每个像素点通常与其相邻的像素点相连。使用sklearn.feature_extraction.image
模块中的grid_to_graph
函数来定义这种连接关系。
from sklearn.feature_extraction.image import grid_to_graph
connectivity = grid_to_graph(*rescaled_coins.shape)
上述代码定义了图像中像素点的连接关系,为后续的聚类算法提供了必要的结构信息。
接下来,使用sklearn.cluster
模块中的AgglomerativeClustering
类来执行层次聚类。设置聚类数为27,并指定使用Ward方法进行聚类。
import time
from sklearn.cluster import AgglomerativeClustering
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()
上述代码首先创建了一个图像显示窗口,并使用灰度颜色映射来显示图像。然后,它遍历每个簇,并在图像上绘制出该簇的轮廓。最后,关闭坐标轴显示,并展示最终的聚类结果图像。