基于聚类均值对kmeans中的分割图像标签进行排序

时间:2015-08-19 14:02:58

标签: algorithm matlab image-processing

我有一个简单的问题,但非常有趣。如您所知,由于随机初始聚类中心,Kmeans在每次运行后可以得到不同的结果。但是,假设我知道群集1的平均值小于群集2,群集2的平均值小于群集3,依此类推。我想制作一个算法来实现该集群具有较小的平均值,然后将其分配给小集群索引。

这是我的Matlab代码。如果你有更多种类或更清晰的方式。请建议我

 %% K-mean
 num_cluster=2;
 nrows = size(Img_original,1);
 ncols = size(Img_original,2);
 I_1D = reshape(Img_original,nrows*ncols,1);
 [cluster_idx    mu]=kmeans(double(I_1D),num_cluster,'distance','sqEuclidean','Replicates',3);
 cluster_label = reshape(cluster_idx,nrows,ncols);
 %% Sort based on mu
 [mu_sort id_sort]=sort(mu);
 idx=cell(1,num_cluster)
 %% Save index of order if mu
 for i=1:num_cluster
    idx{i}=find(cluster_label==id_sort(i));
 end
 %% Sort cluster label based on mu
 for i=1:num_cluster
    cluster_label(idx{i})=i;
 end

1 个答案:

答案 0 :(得分:1)

我不清楚为什么你想根据每个质心的排序重新标记聚类。您可以简单地使用从k-means输出的标记向量来引用每个点所属的簇/质心。

然而,你必须对质心进行排序的初步想法是一个很好的想法。您的代码的最后一部分看起来效率很低,因为您循环遍历每个标签并进行重新分配。我可以建议的一件事是有一个查找表,其中输入是原始标签,输出是基于排序质心的重新排序标签。

如果您想要使用此路线,可以使用containers.Map,其中键是从sort输出的排序顺序给出的标签,值是重新排序的标签。即,一个从1到多个类的向量。您需要执行此操作,因为sort的第二个输出会告诉您原始数组中的每个值在排序结果中的位置,因此您必须使用此顺序来正确执行重新标记。另外,我会在MATLAB中使用sortrows函数,而不是原始sort。根据您的操作方式,您将独立地对每个列/变量进行排序,这将给出错误的质心。这适用于灰度图像,其中您只有一个要考虑的特征,即灰度,但如果您超出灰度并可能进入RGB或您想要的任何颜色空间,使用原始sort将给您不正确的结果。您需要将每一行视为单个点,然后将这些行联合排序。

鉴于您的代码,您可以执行以下操作:

%% K-mean
num_cluster=2;
nrows = size(Img_original,1);
ncols = size(Img_original,2);
I_1D = reshape(Img_original,nrows*ncols,1);
[cluster_idx    mu]=kmeans(double(I_1D),num_cluster,'distance','sqEuclidean','Replicates',3);

%% Sort based on mu
[mu_sort id_sort]=sortrows(mu);

%// New - Create lookup
lookup = containers.Map(id_sort, 1:size(mu_sort,1));

%// Relabel the vector
cluster_idx_sort = lookup.values(num2cell(cluster_idx));
cluster_idx_sort = [cluster_idx_sort{:}];

%// Reshape back to original image dimensions
cluster_label = reshape(cluster_idx_sort,nrows,ncols);

这应该可以为您的代码提供一些加速。

要仔细检查,我在cameraman.tif图像上尝试了这个,这是图像处理工具箱的一部分。运行代码为我提供了这些集群中心:

>> mu

mu =

  153.3484
   23.7291

一旦我按升序对集群进行排序,这就是我获得的排序和质心所得:

>> mu_sort

mu_sort =

   23.7291
  153.3484

>> id_sort

id_sort =

     2
     1

这样就像我们预期的那样......现在如果我们在对质心进行排序之前显示原始的簇标签图,那么:

cluster_label = reshape(cluster_idx, nrows, ncols);
imshow(cluster_label,[]);

...我们得到这张图片:

enter image description here

现在,如果我们运行排序逻辑并显示质心:

imshow(cluster_label, []);

...我们得到这张图片:

enter image description here

这符合我的预期。因为质心翻转,所以应该着色。