Why this program for automatical segmentation doesn´t work?

2 Ansichten (letzte 30 Tage)
Veronika
Veronika am 27 Mär. 2017
Kommentiert: Veronika am 29 Mär. 2017
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.

Antworten (1)

Jan
Jan am 27 Mär. 2017
Bearbeitet: Jan am 27 Mär. 2017
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 Kommentare
Jan
Jan am 29 Mär. 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
Veronika am 29 Mär. 2017
So I just removed rows, where mu==oldmu is and replaced this:
if abs(mu - oldmu) < 1e-6 % Or whatever you accept as converged
break;
end
I´m so sorry, but I don´t understand, what you mean.

Melden Sie sich an, um zu kommentieren.

Community Treasure Hunt

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

Start Hunting!

Translated by