将根据子集计算的kmeans应用于完整数据

时间:2018-08-06 12:34:39

标签: python image-processing k-means image-segmentation

我有一些层析数据集,我想通过k均值聚类将其细分为不同的部分。 由于数据集很大,因此我在数据的子集上计算k均值。 现在,我想将计算出的k均值应用于数据集的较大部分,但是我似乎无法使其正常工作,细分没有正确应用。

我像这样加载图像的子集:

import glob
import imageio
import numpy
filenames = glob.glob(os.path.join(FolderToRead, '*rec0*.tif'))
vol_subset = numpy.stack([imageio.imread(rec) for rec in filenames[::50]], 0)

然后按以下方式计算k均值聚类:

import sklearn.cluster
kmeans_volume = sklearn.cluster.MiniBatchKMeans(n_clusters=6, batch_size=2**11)
subset_clustered = kmeans_volume.fit_predict(numpy.array(vol_subset).reshape(-1,1))
subset_clustered.shape = numpy.shape(vol_subset)

标签看起来很棒,标签1是骨骼,标签3是植入物,标签5是骨骼中的血管。

for c, img in enumerate(subset_clustered):
    for d, cluster in enumerate(range(number_of_clusters)):
        plt.subplot(1, number_of_clusters, d+1)
        # Show original image
        plt.imshow(img)
        # Overlay label image
        plt.imshow(numpy.ma.masked_where(img != d, img), cmap='jet_r')
        plt.title('Image %s/%s, Label %s' % (c + 1, len(vol_clustered), d))
        plt.show()

Labels applied to subset

现在,我已经对数据的子集计算了k均值,我希望将其应用于整个数据集。 我试图这样做,但是标签似乎不一致。

# Apply segmentation calculated above
for c, r in enumerate(reconstructions):
    # Read in all files subsequently
    reconstruction = imageio.imread(r)
    # Label the images with the kmeans calculated from a subset of the images
    clustered_rec = kmeans_volume.fit_predict(reconstruction.reshape(-1, 1))
    clustered_rec.shape = numpy.shape(reconstruction)
    # Write out the images
    imageio.imwrite('filename' + c + '.png, numpy.uint8(clustered_rec == 3) * 255 )  # 3 being the screw label

下图显示了上面脚本的裁剪输出。 左图的一幅图像(中间的五个斑点)上的血管正确标记为5,右图的下一幅图像将其标记为1,这是错误的...

Wrongly applied labels

任何指向我正在做错事情的指针将不胜感激。 我希望我不必在整个数据集上计算k均值,因为有2700张TIFF图像,每个图像的大小为1944x1944像素...

1 个答案:

答案 0 :(得分:2)

根据MiniBatchKMeans的文档,fit_predict(X[, y])“每个样本的计算聚类中心预测聚类索引”

方法predict(X)只有“ 预测 X中每个样本所属的最近的簇。”
因此,只需要在整个数据集上使用这一点。