kmeansクラスタリングアルゴリズムに基づく画像分割

2165 ワード

Kmeansは以前に述べたように、その画像分割は以前のGauss数対を画像の2次元画素点に変えたにすぎず、カラー画像は画素点ごとにrgbの3成分があり、階調画像は1成分しかない.
1プログラミング実装
clear;clc;close all;
data=imread('src1.bmp');
imshow(data)
[m,n,c]=size(data);
[mu,pattern]=k_mean_Seg(data,2);
for x=1:m
    for y=1:n
        if pattern(x,y,1)==1
            data(x,y,1)=0;
            data(x,y,2)=0;
            data(x,y,3)=255;
        elseif pattern(x,y,1)==2
            data(x,y,1)=0;
            data(x,y,2)=255;
            data(x,y,3)=0;
        elseif pattern(x,y,1)==3
            data(x,y,1)=255;
            data(x,y,2)=0;
            data(x,y,3)=0;
        else
            data(x,y,1)=255;
            data(x,y,2)=255;
            data(x,y,3)=0;
        end
    end
end
figure;
imshow(data);   
 
function [num,mask]=k_mean_Seg(src,k)
src=double(src);
img=src;        
src=src(:);      
mi=min(src);     
src=src-mi+1;    
L=length(src);
 
m=max(src)+1;
hist=zeros(1,m);
histc=zeros(1,m);
for i=1:L
  if(src(i)>0)
      hist(src(i))=hist(src(i))+1;
  end;
end
ind=find(hist);
hl=length(ind);
num=(1:k)*m/(k+1);
while(true)
  prenum=num;
  for i=1:hl
      c=abs(ind(i)-num);
      cc=find(c==min(c));
      histc(ind(i))=cc(1);
  end
  for i=1:k,
      a=find(histc==i);
      num(i)=sum(a.*hist(a))/sum(hist(a));
  end
  if(num==prenum)
      break;
  end;
 
end
L=size(img);
mask=zeros(L);
for i=1:L(1),
for j=1:L(2),
  c=abs(img(i,j)-num);
  a=find(c==min(c)); 
  mask(i,j)=a(1);
end
end
num=num+mi-1;  

    
 
2結果展示
  
a)原図b)N=2
 
c)N=3                                                                         d)N=4
階調画像については、data=rgb 2 gray(data)を用いる.階調画像に変換した後の表示は以下のようになります.
for x=1:m
    for y=1:n
        if pattern(x,y)==1
            data(x,y)=0;
        elseif pattern(x,y)==2
            data(x,y,1)=80;
        elseif pattern(x,y)==3
            data(x,y)=180;
        else
            data(x,y)=255;
        end
    end
end
 
a)原図b)N=2
 
c)N=3                                                                         d)N=4