Kmeans聚类(lena图)
lena512.raw 下载地址:https://files.cnblogs.com/files/jzcbest1016/lena512_20171219131444306.rar
.raw文件可以用photoshop打开
#include<stdio.h>
#include<math.h>
#include <stdlib.h>
#define ROW 512
#define COL 512
#define K 8
#define N 512*512
typedef unsigned char BYTE;
int center[N];
BYTE origin[N];
BYTE output[N];
int mean[K];
double cal_psnr(BYTE input[N],BYTE output[N])
{
int i, j;
double PSNR = 0, MSE = 0, MAXI = 255;
for (i=0;i<N;i++)
MSE += (input[i] - output[i]) * (input[i] - output[i]);
MSE = MSE/(ROW*COL);
printf("MSE: %f\n", MSE);
PSNR = 20*log10(MAXI) - 10*log10(MSE);
return PSNR;
}
//计算距离函数,欧式距离
double getdistance(int i,int j)
{
int d;
d = abs(i-j);
return d;
}
//聚类函数
void cluster()
{
for (int i = 0; i < N; i++)
{
double min = 9999.0;
for (int j = 0; j < K; j++)
{
//printf("%d\n",origin[i]);
if(getdistance(origin[i], mean[j])<min)
{
min = getdistance(origin[i], mean[j]);
center[i] = j;
}
}
}
}
//聚类后误差计算函数
double gete()
{
double cnt=0, sum=0;
for (int i = 0; i < N; i++)
{
for (int j = 0; j < K; j++)
{
if (center[i] == j)
{
cnt = getdistance(origin[i], mean[j]);
}
}
sum += cnt;
}
return sum;
}
//重新计算聚类中心
void getmean(int center[N])
{
double sum;
int count;
for (int i = 0; i < K; i++)
{
sum=0;
count = 0;
for (int j = 0; j < N; j++)
{
if (center[j] == i)
{
sum+= origin[j];
count++;
}
}
mean[i] = sum / count;
}
}
int main()
{
FILE *f = NULL;
f = fopen("D:\lena512.raw","rb");
fread(origin,sizeof(BYTE),ROW*COL,f);
printf("has already read\n");
mean[0] = 4;
mean[1] = 50;
mean[2] = 98;
mean[3] = 250;
mean[4] = 23;
mean[5] = 128;
mean[6] = 78;
mean[7] = 80;
int number = 0;
double temp1, temp2;
//第一次聚类
cluster();
number++;//number统计进行了几次聚类
//对第一次聚类的结果进行误差平方和的计算
temp1 = gete();
printf("the error1 is:%f\n", temp1);
//针对第一次聚类的结果,重新计算聚类中心
getmean(center);
//第二次聚类
cluster();
number++;
temp2 = gete();
printf("the error2 is:%f\n", temp2);
//迭代循环,直到两次迭代误差的差值在一定阈值范围内,则迭代停止
while (fabs(temp1 - temp2) > 0.5)
{
temp1 = temp2;
getmean(center);
cluster();
temp2 = gete();
number++;
//printf("the error%d is:%f\n", number,temp2);
}
for (int i = 0;i<N;i++)
output[i] = mean[center[i]];
printf("PSNR: %lf\n",cal_psnr(origin,output));
printf("the total number of cluster is:%d\n", number);
return 0;
}
PNSR,峰值信噪比,是用来衡量图片质量的。
浙公网安备 33010602011771号