为什么k表示颜色分割每次都显示不同的颜色?

why does kmean color segmentation show different color every time?

我正在学习如何使用 kmean 聚类来分割颜色,就像 matlab 2015a 中的示例一样。但是每次我 运行 代码,我想要的颜色都在不同的簇中。例如,对于第一个 运行,它会显示黄色在 cluster 1 中,蓝色在 cluster 2 中。当我再次 运行 时,它们将切换到不同的 cluster。如何使黄色和蓝色在特定的簇中,即使我 运行 一次又一次?请帮我。提前致谢

这是我使用的代码:

[FileName,PathName] = uigetfile('*.jpg','Select the MATLAB code file');

he1= imread(FileName);
cform = makecform('srgb2lab');
lab_he = applycform(he1,cform);
figure (2)
imshow (lab_he)


ab = double(lab_he(:,:,2:3));
nrows = size(ab,1);
ncols = size(ab,2);
ab = reshape(ab,nrows*ncols,2);

nColors = 3;
% repeat the clustering 3 times to avoid local minima
[cluster_idx, cluster_center] = kmeans(ab,nColors,'distance','sqEuclidean',           ...
                                  'Replicates',3);



pixel_labels = reshape(cluster_idx,nrows,ncols);
figure (3)
imshow(pixel_labels,[]), title('image labeled by cluster index');

segmented_images = cell(1,3);
rgb_label = repmat(pixel_labels,[1 1 3]);

for k = 1:nColors
    color = he1;
    color(rgb_label ~= k) = 0;
    segmented_images{k} = color;
end
%%
figure (4)
imshow(segmented_images{1}), title('objects in cluster 1');

%% 
figure (5)
imshow(segmented_images{2}), title('objects in cluster 2');

%%
figure (6)
imshow(segmented_images{3}), title('objects in cluster 3');
%%
a = im2bw (segmented_images{2},0.05);
figure (7)
imshow (a);

b = im2bw (segmented_images{3},0.05);
figure (8)
imshow (b);

在我的情况下,黄色区域应该在集群 2 中,蓝色区域应该在集群 3 中。请告诉我如何操作

kmeans 的第一个输出在集群的 index 中,而不是颜色。您所指的颜色是 MATLAB 在可视化时显示的颜色。

使用 kmeans,初始聚类中心是从输入数据中随机选择的。因此,顺序是随机的。因此,每次调用算法时,将哪个聚类索引分配给像素都会有所不同,但聚类中的像素应放置在同一聚类中,并且彼此具有相同的聚类索引 连续调用。

如果你想要每个簇对应的实际颜色,你会想要使用 kmeanssecond output(簇质心)将簇索引映射到颜色。您可以使用 ind2rgb.

轻松完成此操作
pixel_labels = ind2rgb(cluster_idx, cluster_center);
imshow(pixel_labels)

如果您只是希望簇索引值在连续调用后保持不变,您可以使用cluster_center来确保一致的索引分配

[cluster_idx, cluster_center] = kmeans(ab, nColors);
[~, ind] = sortrows(cluster_center);

pixel_labels = reshape(cluster_idx, nrows, ncols);

for k = 1:numel(ind)
    pixel_labels(cluster_idx == k) = ind(k);
end

如果您希望特定颜色位于特定簇中,可以修改此项。

%// Define yellow
yellow = [1 1 0];

%// Define blue
blue = [0 0 1];

%// Find the centroid closest to yellow
[~, yellowind] = min(sum(bsxfun(@minus, cluster_center, yellow).^2, 2));

%// Find the one closest to blue
[~, blueind] = min(sum(bsxfun(@minus, cluster_center, blue).^2, 2));

%// Now assign them to clusters with yellow as 2 and blue as 3
segmented_images{1} = cluster_idx == setdiff(1:3, [yellowind, blueind]);
segmented_images{2} = cluster_idx == yellowind;
segmented_images{3} = cluster_idx == blueind;