图像硬币分割的分层聚类分析

在本教程中,将通过一个示例来展示如何利用Ward分层聚类算法对一个包含多个硬币的2D图像进行分割。这种聚类方法在空间上是有限制的,确保每个分割区域都是连续的。分层聚类是一种常用的图像分割技术,它能够将图像中的相似区域组合在一起,形成不同的聚类。

数据生成

首先,需要生成或获取硬币图像的数据。在这个示例中,使用了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))

定义数据结构

在进行聚类之前,需要定义数据的结构。在这个示例中,使用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.pyplot模块来展示聚类的结果。通过在原始图像上绘制轮廓线,可以清晰地看到每个硬币的分割效果。

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()

通过上述代码,可以看到每个硬币都被成功地分割出来,尽管设置的聚类数量比实际的硬币数量要多,因为聚类算法还识别了背景中的一些区域。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485