ورود

View Full Version : قطعه بندی تصویر از طریق خوشه بندی



mahsava
شنبه 27 دی 1393, 22:54 عصر
یک کد قطعه بندی تصویر با استفاده از خوشه بندی (الگوریتم k-means) دارم. اما وقتی اون رو بر روی تصویر (خاکستری) اعمال می کنم، خطا میده که اندیس باید عدد صحیح مثبت یا عدد منطقی باشه.
حالا من نمی دونم باید کد رو چطور اصلاح کنم که این خطا رفع بشه و برنامه درست کار کنه. کسی می تونه کمکم کنه؟ درضمن گویا این کد خیلی معروفه و زیاد ازش استفاده می کنن.

این هم کدش:


function [mu,mask]=kmeans(ima,k)% check image
%ima=imread('Robat.jpg');
% greyLevels=2^8-1; % Number of gray levels
% ima=round(greyLevels*ima/max(ima));
ima=double(ima);
copy=ima; % make a copy
ima=ima(:); % vectorize ima (colunm)
mi=min(ima); % deal with negative
ima=ima-mi+1; % and zero values (sefr va manfi ro az beyn mibare)
%k=6;


s=length(ima);


% create image histogram


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


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; % recover real range

rahnema1
یک شنبه 28 دی 1393, 11:02 صبح
سلام
این جوری

function [mu, mask]=kmeans(ima, k)
img_size = size(ima);
ima = double(ima);
mask = uint8(zeros(img_size));
uniqvals = unique(ima);
%init mu
mu = sort(uniqvals(randperm(numel(uniqvals), k)));
mutemp = zeros(size(mu));
ans1 = logical(zeros(img_size));
while (true)
minDistance = abs(ima - mu(1));
mask(:) = 1;
for i = 2: k
tempDistance = abs(ima - mu(i));
ans1 = minDistance < tempDistance;
mask = ans1 .* mask + ~ans1 .* i ;
minDistance = min (minDistance, tempDistance);
end
for i = 1: k
mutemp(i) = mean(ima(mask == i));
end
if ( all(mu == mutemp))
break;
end
mu = mutemp;
end
end

mahsava
یک شنبه 28 دی 1393, 12:31 عصر
ممنون از راهنماییتون.
من این کد رو اجرا کردم ولی خطا داد. شما تابع randperm خودتون رو تعریف کردین؟
این هم خطاش:

??? Error using ==> randperm
Too many input arguments.


Error in ==> myKmeans at 7
mu =
sort(uniqvals(randperm(numel(uniqvals),
k)));

rahnema1
یک شنبه 28 دی 1393, 13:48 عصر
فکر کنم از متلب نسخه قدیمی استفاده می کنید
کد مربوط به mu را به این تغییر بدید

randomindex = randperm(numel(uniqvals));
mu = sort(uniqvals(randomindex(1:k)));

mahsava
یک شنبه 28 دی 1393, 14:35 عصر
شما از چه نسخه ای استفاده می کنید؟ نسخه ی من مال سال 2010 هست (7.10.0.499). با این جمله هم مشکل داره:
mask = ans1 .* mask
شما چی توصیه می کنید؟ اگه نسخه اش خیلی تغییر پیدا کرده، جدیدشو نصب کنم.

rahnema1
یک شنبه 28 دی 1393, 14:56 عصر
من از برنامه ای به نام octave استفاده می کنم که شبیه متلبه با این تفاوت که اپن سورسه
در مورد randperm میدونم که نسخه های قبلی ساپورت نمیکنه
اما این مورد را دقیقا نمیدونم
فکر کنم اینجور اصلاح بشه
mask = uint8(ans1) .* mask + uint8(~ans1) .* i ;

mahsava
یک شنبه 28 دی 1393, 16:03 عصر
مرسی. درست شد.