Sort clusters using K-means by intensity

13 Ansichten (letzte 30 Tage)
Xen
Xen am 29 Mai 2015
Bearbeitet: Xen am 31 Mai 2015
Hello everyone. I am using K-means to segment some grayscale images. Unfortunately, the values of the generated clusters are not repeatable, i.e. every time I run the code the clusters have a different value. For example, if I use k=2 sometimes the darker areas of the original image have a cluster value of 1 and sometimes 2 (before normalisation). How to sort/order the generated clusters to have a value corresponding to the actual grayscale intensities, i.e. darkest = 1, less dark = 2,... brightest = k ? Thanks. Here is the code:
% Clustering.
clustered = reshape(kmeans(inputimage(:), k), size(inputimage));
% Normalise intensities from 0 to 1.
clustered = clustered - min(clustered(:));
clustered = clustered / max(clustered(:));

Akzeptierte Antwort

Walter Roberson
Walter Roberson am 29 Mai 2015
You are normalizing the indices, not by cluster intensities.
kidx = kmeans(inputimage(:), k);
clustermeans = accumarray(kidx, inputimage(kidx),[], @mean);
[sortedmeans, sortidx] = sort(clustermeans);
kidxmapped = sortidx(kidx);
clustered = reshape(kidxmapped, size(inputImage));
  9 Kommentare
Xen
Xen am 31 Mai 2015
Yeeess! I finally cracked this. I created a method to sort the clustermeans appropriately, and also had to use a different method to create clustermeans otherwise it kept failing. This is quite slow for large k values. If you have any suggestions for improvement I would be glad to know.
% Cluster.
clustered = reshape(kmeans(image(:), k), size(image));
% Sort clusters.
clustermeans = zeros(k, 1);
for j = 1:k
[row, col] = find(clustered == j);
pixelsKvalued = zeros(length(row), 1);
for l = 1:length(row)
pixelsKvalued(l) = image(row(l), col(l));
end
clustermeans(j) = mean(pixelsKvalued);
end
sortidx = zeros(k, 1);
for j = 1:k
sortidx(find(clustermeans == min(clustermeans))) = j;
clustermeans(clustermeans == min(clustermeans)) = NaN;
end
clustered = sortidx(clustered);
Xen
Xen am 31 Mai 2015
Bearbeitet: Xen am 31 Mai 2015
No need to estimate the mean of all pixels representing each cluster. Just a single pixel will do. Thanks Walter, this was inspired by your suggestions.
% Cluster.
clustered = reshape(kmeans(image(:), k), size(image));
% Sort clusters.
clusterintensity = zeros(k, 1);
for j = 1:k
clusterintensity(j) = image(find(clustered == j, 1));
end
clusteridx = zeros(k, 1);
for j = 1:k
clusteridx(find(clusterintensity == min(clusterintensity))) = j;
clusterintensity(clusterintensity == min(clusterintensity)) = NaN;
end
clustered = clusteridx(clustered);

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by