基于K-Means的图像分割算法(matlab代码)

1.1
K-Means算法的基本原理

非监督分类(Unsupervised
Classification)通常也叫做点群分类。非监督分类的处理过程较简单,只是单纯的统计图像地物的光谱特征信息进行分类,不需要利用图像地物的先验知识。非监督分类方法与监督分类方法的不同的在于非监督分类方法不需要分类先验知识,该方法认为图像上的同类物体必定反射出相同的或者相似的(接近的)光谱特征,这些特征之间必定存在某种关联关系,所以它们自然地聚集在一起同属于一个光谱特征区域,而异类物体反射的光谱特征自然会不一样的,因而它们聚不到一起,自然处于不同的光谱特征空间里。总之,非监督分类方法在没有分类先验知识的情况,根据物体光谱特征的自然聚集而成的一种分类方法。
在这里插入图片描述

1.1 2
K-Means法实现步骤

K-Means的聚类规则是:对于每一类的聚类,使多个像素到这个类中心的距离平方和要最小,即多个模式点到该模式类中心的距离平方和要最小。一般方法是先按某些原则选择一些代表点作为聚类中心,然后把其余的待分点按某种方法(判别准则)分到各类别中去,完成初始分类。初始分类完成以后,重新计算各聚类中心,完成第一次迭代。然后修改聚类中心,以便进行下一次迭代。

这种方法原本就是迭代的,并且无法确保它总是收敛于全局最优解。均值的性能依赖于聚类中心的初始位置。因此,为了将结果更好地迭代到全局最优解,可以用一些方法得到最佳的初始聚类中心;或者通过选择不同的初始聚类中心来试验这个算法。由于均值算法代表的是一种典型,因此能选择尝试对任选的一个隶属矩阵进行初始化,再对迭代过程进行实施。

其具体步骤如下所示:
在这里插入图片描述

function [F,C]=imkmeans(I,C)
if nargin~=2
    error('IMKMEANS:InputParamterNotRight','只能有两个输入参数!');
end
if isempty(C)
    K=2;
    C=[];
elseif isscalar(C)
    K=C;
    C=[];
else
    K=size(C,1);
end
X=exactvecotr(I);
if isempty(C)
    C=searchintial(X,'sample',K);
end
Cprev=rand(size(C));
while true
    D=sampledist(X,C,'euclidean');
    [~,locs]=min(D,[],2);
    for i=1:K
        C(i,:)=mean(X(locs==i,:),1);
    end
    if norm(C(:)-Cprev(:))<eps
        break
    end
    Cprev=C;
end
[m,n,~]=size(I);
F=reshape(locs,[m,n]);
function vec=exactvecotr(img)
[m,n,~]=size(img);
vec=zeros(m*n,3);
img=double(img);
for j=1:n
    for i=1:m
        color=img(i,j,:);
        dist=[];
        texture=[];
        vec((j-1)*m+i,:)=[color(:);dist(:);texture(:)];
    end
end
function C=searchintial(X,method,varargin)
switch lower(method(1))
    case 's' 
        K=varargin{1};
        C=X(randsample(size(X,1),K),:);
    case 'u' 
        Xmins=min(X,[],1);
        Xmaxs=max(X,[],1);
        K=varargin{1};
        C=unifrnd(Xmins(ones(K,1),:), Xmaxs(ones(K,1),:));
end
function [center]=searchcenter(X,kratio)
[n,~]=size(X);
isleft=true(n,1);
count=zeros(n,1);
center=[];
kind=0;
dist=0;
for i=1:n
    for j=i+1:n
        dist=dist+weightdist(X(i,:),X(j,:));
    end
end
dist=dist/((n-1)*(n-1)/2);
radius1=dist*kratio(1);
radius2=dist*kratio(2);
while any(isleft)
    for i=1:n
        count(i)=0;
        if isleft(i)       
            for j=1:n
                if isleft(j)
                    dist=weightdist(X(i,:),X(j,:));
                    count(i)=count(i) + dist<=radius1;
                end
            end
        end
    end
    [~,locs]=max(count);
    iscenter=true;
    for i=1:kind
        dist=weightdist(X(locs,:),center(i,:));
        iscenter=iscenter && dist>=radius2;
        if ~iscenter
            break;
        end
    end
    if iscenter
        kind=kind+1;
        center(end+1,:)=X(locs,:);
        for i=1:n
            if isleft(i)
                dist=weightdist(X(i,:),X(locs,:));
                if  dist <= radius1
                    isleft(i)=false;    
                end
            end        
        end        
    else
        isleft(locs)=false;
    end
end
function D=sampledist(X,C,method,varargin)
[n,p]=size(X);
K=size(C,1);
D=zeros(n,K);
switch lower(method(1))
    case 'e'
        for i=1:K
            D(:,i)=(X(:,1)-C(i,1)).^2;
            for j=2:p
                D(:,i)=D(:,i)+(X(:,j) - C(i,j)).^2;
            end
        end
    case 'c'
        for i=1:K
            D(:,i)=abs(X(:,1) - C(i,1));
            for j=2:p
                D(:,i)=D(:,i) + abs(X(:,j) - C(i,j));
            end
        end
end

效果图:
在这里插入图片描述

原创文章 21 获赞 0 访问量 2746

猜你喜欢

转载自blog.csdn.net/durzak/article/details/105135788