k均值聚类算法(k-means clustering algorithm)是一种迭代求解的聚类分析算法,其步骤是,预将数据分为K组,则随机选取K个对象作为初始的聚类中心,然后计算每个对象与各个种子聚类中心之间的距离,把每个对象分配给距离它最近的聚类中心。聚类中心以及分配给它们的对象就代表一个聚类。每分配一个样本,聚类的聚类中心会根据聚类中现有的对象被重新计算。这个过程将不断重复直到满足某个终止条件。终止条件可以是没有(或最小数目)对象被重新分配给不同的聚类,没有(或最小数目)聚类中心再发生变化,误差平方和局部最小。
基于kmeans分割
k-means 算法,也被称为 k-均值,是一种得到最广泛使用的聚类算法。其认为两个目标的距离越近,相似度越大。算法的主要思想是通过迭代来把数据划分为不同的类别,使得评价聚类性能的准则函数达到最优,从而使生成的每个聚类内紧凑,类间独立。
%kmeans
clc;
clear;
close all;
fg=im2double(imread('hai.png'));
[M,N]=size(fg);
subplot(221),imshow(fg),title('原图');
hsv=rgb2hsv(fg);
h=hsv(:,:,1);
h(h>330/360)=0;%接近360°的色调认为是0°
training=h(:);%获取训练数据
startdata=[0;60/360;120/360;180/360;240/360;300/360];%初始点数据
% [IDX,C]=kmeans(training,6,'start',startdata);
[IDX,C]=kmeans(training,6,'start',startdata);%调用自带函数
[MinVal,Num]=k_means(training,6,startdata);%调用自编函数
idbw1=(IDX==1);%取边缘
template1=reshape(idbw1,size(h));%二值化图像
idbw2=(Num==1);
template2=reshape(idbw2,size(h));
subplot(222),imshow(template1),title('k均值聚类分割');
subplot(223),imshow(template2),title('k均值聚类分割1.0');
R=fg(:,:,1);
G=fg(:,:,2);
B=fg(:,:,3);
R1=R.*double(template1);
G1=G.*double(template1);
B1=B.*double(template1);
templateR=cat(3,R1,G1,B1);
subplot(224),imshow(templateR),title('k均值聚类分割2.0');
function [MinVal,Num] = k_means(training,k,startdata)
dist=zeros(size(training,1),k);
for m=1:k
dist(:,m)=sqrt((training-startdata(m)).^2);
end
[MinVal,Num]=min(dist,[],2);
end
输出:
通过计算欧式距离来迭代的k均值聚类分割
欧氏距离公式
步骤
(1)从N个数据文档(样本)随机选取K个数据文档作为质心(聚类中心)。
(2)对每个数据文档测量其到每个质心的距离,并把它归到最近的质心的类。
(3)重新计算已经得到的各个类的质心。
(4)迭代(2)~(3步直至新的质心与原质心相等或小于指定阈值,算法结束。
欧式聚类分割,其分割结果有一定规律:聚类点数由多到少依次进行分割。
%通过计算欧式距离来迭代的k均值版本
clear;
clc;
close;
fg=rgb2gray(imread('hai.png'));
subplot(121),imshow(fg),title('原图');
[M,N]=size(fg);%获取图像的大小
%随机初始化聚类中心
h=double(fg);
k=4;
training=h(:);%training是N*n的向量,每行对应一个点,每点为n维度;k为要聚成的类别数
startdata=randperm(size(training,1));%随机生成初始点
startdata=double(fg(startdata(1:k)));%获取对应初始点的灰度值
startdata(1)=0;%设置第一类灰度值中心为;
flag=false;%设置脱离循环的变量
dist=zeros(size(training,1),k);%预设置dist的大小(理论上能提高运算速度)
while ~flag%为ture时运行,flag==false取反运行,false==0,ture==1
for m=1:k
dist(:,m)=sqrt((training-startdata(m)).^2);%计算每个点到初始点的距离
end
[MinVal,Num]=min(dist,[],2);%min(dist,[],2)函数选出每行最小的点放于MinVal,
%并选出的它的列索引(分类依据,第几列就是第几类)放于Num
for m=1:k
Temp(:,m)=mean(fg(find(Num==m)));%计算每个类别的均值
end
flag=max(Temp-startdata)<0.1;%判断前后两次迭代的中心点灰度值的差值是否相同,0.1为判断的阈值
if flag==1%如果两次迭代中心点取值相同flag==1跳出循环;
break
else
startdata=Temp;%否则再次迭代
end
end
% [MinVal,IDX]=min(dist,[],2);
idbw=(Num==1);
template=reshape(idbw,size(h));
subplot(122),imshow(template),title('k均值聚类分割');
输出: