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,峰值信噪比,是用来衡量图片质量的。

 

posted @ 2018-02-28 17:59  Cheney_1016  阅读(574)  评论(0编辑  收藏  举报