algorithm - Sort labels of segmented image in kmeans based on cluster mean -
i have simple question interesting. know, kmeans can give different result after each running due randomly initial cluster center. however, assume know cluster 1 has smaller mean value cluster 2, cluster 2 has smaller mean value cluster 3 , on. want make algorithm implement cluster has small mean value, assigned small cluster index.
this matlab code. if have more sort or more clear way. please suggest me
%% 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 i=1:num_cluster idx{i}=find(cluster_label==id_sort(i)); end %% sort cluster label based on mu i=1:num_cluster cluster_label(idx{i})=i; end
it's unclear me why you'd want relabel clusters based on ordering of each centroid. can use labelling vector output k-means reference cluster / centroid each point belongs to.
nevertheless, initial idea had sort centroids one. last part of code seems rather inefficient because you're looping on each label , doing reassignment. 1 thing perhaps suggest have lookup table input original label , output reordered labels based on sorted centroids.
if want pursue route, can use containers.map
keys labels given sort order output sort
, , values reordered labels... namely, vector goes 1 many classes have. need because second output of sort
tells each value in original array appear in sorted result, must use ordering perform relabelling. in addition, use sortrows
function in matlab, not raw sort
. how you're doing it, sorting each column / variable independently , give wrong centroids. work grayscale images have 1 feature consider, namely grayscale, if go beyond grayscale , perhaps go rgb or whatever colour space desire, using raw sort
give incorrect results. need consider each row single point, sort rows jointly.
given code, you'd this:
%% 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 vector cluster_idx_sort = lookup.values(num2cell(cluster_idx)); cluster_idx_sort = [cluster_idx_sort{:}]; %// reshape original image dimensions cluster_label = reshape(cluster_idx_sort,nrows,ncols);
this should give speedup in code.
to double check, tried on cameraman.tif
image, that's part of image processing toolbox. running code gives me these cluster centres:
>> mu mu = 153.3484 23.7291
once sort clusters in ascending order, ordering , centroids:
>> mu_sort mu_sort = 23.7291 153.3484 >> id_sort id_sort = 2 1
so works expected... if display original cluster label map before sorting on centroids with:
cluster_label = reshape(cluster_idx, nrows, ncols); imshow(cluster_label,[]);
... image:
now, if run through sorting logic , display centroids:
imshow(cluster_label, []);
... image:
this works expected. because centroids flipped, should colouring.
Comments
Post a Comment