基于聚类算法的图像分割技术

本科毕业设计,在此总结。

1. 聚类概念

如今,学术界并未对聚类作出一个具体定义。目前,认可度最高的观点是:聚类是一种无监督的分类手段。无标签的数据集可通过聚类分析中设定的相似性度量进行分类,形成多个类簇,满足实验的分析需要。因聚类本身是一种具有主观性且能获得良好效果的研究手段,无严格意义上的对错之分,只有“类内的相似和类它的排斥”这一基本准则。1974年,Everitt对聚类作出基础定义:基于任一相似度准则,同一类簇的样本数据具有相似特性,不同类簇的样本数据不相似。相似度准则由研究所需实验效果而定。类簇指数据集中相似样本点的汇聚。聚类要求同一类簇中的点相对密集,不同类簇间点的最小距离大于任意两个同一类簇点的距离。

1.1 基于划分的聚类算法

基于划分的聚类算法基本思想是将数据集中的样本点分成若干个子集(簇),且每个样本点只属于一个子集(簇),数学表达如下所示。划分聚类需预先给定聚类的数目或聚类中心,根据相似性度量的取值结果进行划分,使数据值靠近聚类中心。并设定聚类收敛准则,通过迭代计算更新聚类中心,对数据进一步划分,当目标函数收敛时即达到理想的聚类效果。

基于聚类算法的图像分割技术_第1张图片

1.2 基于层次的聚类算法

基于层次的聚类算法基本思想是将数据样本进行层次分解。该算法是一种树形结构算法,基本思想是通过计算所属不同类簇的数据间的相似性度量,构建一个嵌套型聚类树。按照树形结构不同,可分为凝聚型层次聚类(Agglomerative Hierarchical Clustering)和分裂型层次聚类(Divisive Hierarchical Clustering)两种类型。凝聚型层次聚类运算形式为自底向上,即每个数据对象都放在不同的类簇中,通过相似性度量计算逐渐融合相近的类簇,直至融合为一类或达到某个阈值而终止。与之相反,分裂型层次聚类是自顶向下,所有数据对象都置于同一类簇,每一次运算后将会把大类簇分为更小的类簇。通过不断迭代,直至将每个数据对象置于不同类或达到某个收敛条件而终止。数学形式如下所示:

1.3 基于密度的聚类算法

基于密度的聚类算法创新性地提出了数据集是低密度区域与高密度类簇的集合这一新的认识角度。基于密度的聚类算法的中心思想是:若数据样本间的密度高于某个阈值,则将继续进行分割。即每个类簇中必须包含一定密度的数据点。

1.4基于网格的聚类算法

基于网格的聚类算法将整个数据集划分为数目有限个独立单元,构成可以实现聚类的网络结构。所有的数据处理均在网络结构上实现。该算法的优点在于运算速度快,可结合多种聚类算法形成不同的类簇结果。

2 基于K-Means算法的图像分割实验

K-means算法归属于基于划分的聚类算法,由于具有易于实现和分割效果好等优点,故在各个领域具有广阔的应用前景。K-means算法的基本步骤为:

(1)根据样本特征设定K个聚类中心。
(2)计算各个聚类中心邻域内的像素与该中心的相似性度量,将像素划分给相似性度量取值最大所属的簇,再计算每个簇数据的均值。
(3)将该均值作为新的聚类中心,不断迭代计算。当优化函数满足收敛条件(即聚类中心点不再更新),则停止计算,得到聚类结果。

该算法将误差平方和作为判定聚类中心是否发生变化的评判准则。计算各个类簇内所含样本点距离中心的欧式距离的平方,也即计算每个类簇的误差。因初始设定类簇个数不同,划分的类簇也会有差异。若在两次初始参数设置不同的实验中,误差平方和越小,分割效果越好。若在同一次实验中,前后两次误差平方和在一个很小的范围内波动,则认为已收敛,结束运算。算法原理如下所示:
基于聚类算法的图像分割技术_第2张图片

3. 实验结果

基于聚类算法的图像分割技术_第3张图片
将每幅样本图像的聚类数从2取至9,逐一比较叶片图像的分割结果,实验结果如图上所示。

22/4/9 填坑了
*

4 算法实现

首先是主程序`

*`clc
close all
I=imread('xx.bmp'); ##输入一个二维图像,对格式没有要求
I=double(I)/255; #处理为二值
L=GLCM(I); #提取图像中的灰度纹理
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 

其次,着重看一下这个进行kmeans函数:

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(:))

接着,提取特征向量:

function vec=exactvecotr(img) #输入变量依旧是图像矩阵
[m,n,~]=size(img);
vec=zeros(m*n,3);
img=rgb2lab(img); #图像颜色模型转换
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=[];
%         GLCM(img);
        vec((j-1)*m+i,:,:)=[color(:)];#堆叠在这就行
    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

然后,寻找初始点和聚类中心:(这块原理忘得有点多,后续补)

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

这样就可以进行基本的聚类了。
有问题留言就行,一起进步。

你可能感兴趣的:(机器学习,1024程序员节,聚类,算法,机器学习,图像处理)