Why this program for automatical segmentation doesn´t work?
Show older comments
Dear all,
I have this code for automatical segmentation, but I don´t have output, MATLAB is only "busy".
function [mu,mask]=kmeans(ima,k)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% kmeans image segmentation
%
% Input:
% ima: grey color image
% k: Number of classes
% Output:
% mu: vector of class means
% mask: clasification image mask
%
% Author: Jose Vicente Manjon Herrera
% Email: jmanjon@fis.upv.es
% Date: 27-08-2005
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% check image
k=3;
ima = 'thorax-mdl.jpg';
ima=double(ima);
copy=ima; % make a copy
ima=ima(:); % vectorize ima
mi=min(ima); % deal with negative
ima=ima-mi+1; % and zero values
s=length(ima);
% create image histogram
ima=round(ima);
m=max(ima)+1;
h=zeros(1,m);
hc=zeros(1,m);
for i=1:s
if(ima(i)>0) h(ima(i))=h(ima(i))+1;end;
end
ind=find(h);
hl=length(ind);
% initiate centroids
% k=str2double(k);
mu=(1:k)*m/(k+1);
% start process
while(true)
oldmu=mu;
% current classification
for i=1:hl
c=abs(ind(i)-mu);
cc=find(c==min(c));
hc(ind(i))=cc(1);
end
%recalculation of means
for i=1:k,
a=find(hc==i);
mu(i)=sum(a.*h(a))/sum(h(a));
end
if(mu==oldmu) break;end;
end
% calculate mask
s=size(copy);
mask=zeros(s);
for i=1:s(1),
for j=1:s(2),
c=abs(copy(i,j)-mu);
a=find(c==min(c));
mask(i,j)=a(1);
end
end
mu=mu+mi-1;
imshow(mask,[])% recover real range
I don´t know, why I don´t have any output.I attach original image. Can you advise me?
Thank you for your answers.
Answers (1)
Then obviously the condition if mu==oldmu is never true. This can happen even in the case of convergence if the result oscillate e.g. in the last sigfnificant digit.
You can monitor this easily:
count = 0;
while (true)
...
count = count + 1;
if count > 1000
sprintf('%d iterations reached: mu = %.16g, oldmu = %.16g\n', count, mu, oldmu);
end
if (mu==oldmu) break; end
end
Most likely a tolerance helps:
if abs(mu - oldmu) < 1e-6
break;
end
5 Comments
Veronika
on 28 Mar 2017
Your code still contains "oldmu==mu". As explained already, tiny rounding errors will let this fail.
Use the auto-indentation to find the misplaced "end":
while(true)
...
if (mu==oldmu) break; end
end % ***
% if(mu==oldmu) break;end;
end
Now the function kmeans() is finished. The next line
% calculate mask
s=size(copy);
Appears outside of any function, which is an error. I assume the end marked with * is wrong.
Veronika
on 29 Mar 2017
Jan
on 29 Mar 2017
Sorry, Veronika, I'm telling you the third time now, that "mu==oldmu" cannot be expected to happen. The limited precision can lead to oscillating rounding effects even if te algorithm has converged. Inserting this command twice does not help also.
Please insert a tolerance:
if abs(mu - oldmu) < 1e-6 % Or whatever you accept as converged
break;
end
Veronika
on 29 Mar 2017
Categories
Find more on Color Segmentation in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!