基于K-means聚类算法的MATLAB图像分割

2021-07-30 10:38:15 浏览数 (1)

一、K-means聚类算法原理

K-means算法首先从数据样本中选取K个点作为初始聚类中心;其次计算各个样本到聚类的距离,把样本归到离它最近的那个聚类中心所在的类:然后计算新形成的每个聚类的数据对象的平均值来得到新的聚类中心;最后重复以上步骤,直到相邻两次的聚类中心没有任何变化,说明样本调整结束,聚类准则函数达到最优。

二、K-means聚类算法的要点

1.选定某种距离作为数据样本间的相似性度量

在计算数据样本之间的距离时,可以根据实际需要选择某种距离作为样本的相似性度量,距离越小,样本越相似,差异越小;距离越大,样本越不相似,差异越大。

2.聚类中心迭代终止判断条件

K-means算法在每次迭代中都要考察每个样本的分类是否正确,若不正确,则需要调整。

3.误差平方和准则函数评价聚类性能

三、基于 K-means图像分割

K-means聚类算法简捷,具有很强的搜索力,适合处理数据量大的情况,在数据挖掘

和图像处理领域中得到了广泛的应用。采用K-means进行图像分割,将图像的每个像素点的灰度或者RGB作为样本(特征向量),因此整个图像构成了一个样本集合(特征向量空间),从而把图像分割任务转换为对数据集合的聚类任务。然后,在此特征空间中运用K-means聚类算法进行图像区域分割,最后抽取图像区域的特征。

以下附上图像分割所需要的所有m文件代码。

代码语言:javascript复制
% 1.计算样本之间距离
function D=sampledist(X,C,method)
[n,p]=size(X);
k=size(C,1);
D=zeros(n,k);
switch lower(method(1))
    case 'e' %euclidean即欧氏距离
        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' %cityblock即城市距离
        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
代码语言:javascript复制
%2.提取特征向量
function vec=extractvecotr(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,:);
        %提取距离特征
        wx=1;wy=1;
        dist=[wx*j/n,wy*i/m];
        dist=[];
        %提取纹理特征
        texture=[];
        %组成特征向量
        vec((j-1)*m i,:)=[color(:);dist(:);texture(:)];
    end
end
代码语言:javascript复制
%3.搜索样本空间初始聚类中心
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
代码语言:javascript复制
%4.图像聚类分割
function [F,C]=imkmeans(I,C)
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]);

需要调用的函数编辑好之后就可以读取图像进行调试和使用。

代码语言:javascript复制
clc
close all
I=imread('IMG1.jpg');
I=double(I)/255;
subplot(2,3,1),imshow(I),title('原始图像')
 for i=2:6
F=imkmeans(I,i);
subplot(2,3,i);
imshow(F,[]);
title(['聚类个数=',num2str(i)])
end

经过2-6个聚类个数分割的结果如图所示,不同的图像可以根据情况调整聚类个数以便于达到理想效果。

以上就是今天介绍的基于K-means聚类算法的MATLAB图像分割,有需要的朋友们可以自己动手尝试,欢迎大家分享到朋友圈,让更多有需要的朋友看到!也欢迎更多MATLAB爱好者和使用者前来交流!

参考资料:

[1]陈刚、魏晗、高毫林.MATLAB在数字图像处理中的应用

[2]杨文茵、徐丽新.MATLAB R2016a数字图像处理算法分析与实现

0 人点赞