基于 K-means 的图像分割
一、实验目的
通过 K-means 聚类实现图像分割。
二、算法概要
图像分割就是把图像分成若干个特定的、具有独特性质的区域并提出感兴趣目标的技术和过程。它是由图像处理到图像分析的关键步骤。现有的图像分割方法主要分以下几类:基于阀值的分割方法、基于区域的分割方法、基于边缘的分割方法以及基于特定理论的分割方法等。近年来,研究人员不断改进原有的图像分割方法并把其它学科的一些新理论和新方法用于图像分割,提出了不少新的分割方法。
K-means 算法是很典型的基于距离的聚类算法,采用距离作为相似性的评价指标,即认为两个对象的距离越近,其相似度就越大。该算法认为簇是由距离靠近的对象组成的,因此把得到紧凑且独立的簇作为最终目标。
算法过程如下:
1)从 N 个文档中选取 K 个文档作为质心;
2)对剩余的每个文档测量其到每个质心的距离,并把它归到最近的质心的类;
3)重新计算已经得到的各个类的质心;
4)迭代 2——3 步直至新的质心与原质心相等或者小于制定阀值,算法结束。
三、算法的具体步骤
输入:k,data[n];
(1) 选择 k 个初始中心点,例如 c[0] = data[0], ……,c[k-1]=data[k-1];
(2) 对于 data[0],……,data[n],分别与 c[0],……,c[k-1]比较,假设 c[i]差值最少,就标记为 i;
(3) 对于所有标记为 i 点,重新计算 c[i]={所有标记为 i 的 data[i]z 之和}/标记为 i 的个数;
(4) 重复(2)(3),直至所有 c[j]值的变化小于给定阈值。
四、程序说明
/需要添加内容/
int c[2];
int i,temp1,temp2,j=0,k=0;
int d1,d2,sub1,sub2;
unsigned char sum1,sum2;
char data1[N];
char data2[N];
unsigned char a[N];
c[0] = bmpimage.imgbuf[0];//取第一个元素作为一类中心
c[1] = bmpimage.imgbuf[1];//第二个元素作为二类中心
do
{
for(i = 0;i<N; i++)
{
temp1=abs(bmpimage.imgbuf[i]-c[0]);//欧式距离
temp2=abs(bmpimage.imgbuf[i]-c[1]);
if(temp1<temp2)
{
data1[j]=bmpimage.imgbuf[i];
j++;
sum1 = sum1 + data1[j];//和相加
a[i] = 0;//第一类
}
else
{
data2[k]=bmpimage.imgbuf[i];
k++;
sum2 = sum2 + data2[k];
a[i] = 100;//第二类
}
}
d1 = c[0];
d2 = c[1];
c[0] = sum1/j;//再次求均值
c[1] = sum2/k;
sub1 = d1 - c[0];//终止条件
sub2 = d2 - c[1];
}
while(sub1<0.0001 && sub2<0.0001);
for(i=0;i<N;i++)
{
bmpimage.imgbuf[i] = a[i];
}
五、仿真结果
原图:

仿真后:

