任务要求
读入一个24bitRGB文件(以down.rgb为例,其分辨率为256*256),输出该数据文件中R、G、B三个分量(各8bit表示)的概率分布示意图(类似下图)和熵。
思路
- 分别读取RGB数据(注意BGR的顺序存储)
- 计算概率分布和熵
- 导出数据做图
代码
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define width 256
#define height 256
void count(unsigned char *data, int *count,int i,double *freq)
{
int n=0,m=0;
for(n=0;n<i;n++)
{
for(m=0;m<256;m++)
if(data[n]==m)
count[m]++;
}
for(m=0;m<256;m++)
freq[m]=(double)count[m]/i;
}
int main(void)
{
unsigned char B_data[width*height]={0};//存放RGB原始数据
unsigned char G_data[width*height]={0};
unsigned char R_data[width*height]={0};
int B_count[256]={0},G_count[256]={0},R_count[256]={0};//存放RGB统计数据
double B_freq[256]={0},G_freq[256]={0},R_freq[256]={0};
double B_entropy=0,G_entropy=0,R_entropy=0;
int i=0,n=0,m=0;
int b=0,g=0,r=0;
FILE *fp,*fp_B,*fp_G,*fp_R;
if((fp=fopen("down.rgb","rb"))==NULL)//打开文件
{ printf("Cannot open down.rgb.\n");
getchar();
exit(0);
}
if((fp_B=fopen("B_sat.txt","w"))==NULL)
{ printf("Cannot open B_sat .\n");
getchar();
exit(0);
}
if((fp_G=fopen("G_sat.txt","w"))==NULL)
{ printf("Cannot open G_sat.\n");
getchar();
exit(0);
}
if((fp_R=fopen("R_sat.txt","w"))==NULL)
{ printf("Cannot open R_sat.\n");
getchar();
exit(0);
}
while (!feof(fp))//读出文件的RGB分量
{
if (i==0)
{
B_data[b]=fgetc(fp);
b++;
}
else if (i==1)
{
G_data[g]=fgetc(fp);
g++;
}
else if (i==2)
{
R_data[r]=fgetc(fp);
r++;
}
if(i==2)
i=0;
else
i++;
}
//printf("%d %d %d %d\n", i,r,g,b);
count(B_data,B_count,width*height,B_freq);//统计数据
count(G_data,G_count,width*height,G_freq);
count(R_data,R_count,width*height,R_freq);
fprintf(fp_B,"Symol\tFreq_B\n"); //输出RGB数据的概率分布
for (m=0;m<256;m++)
{
fprintf(fp_B,"%d\t\t%.8f\n",m,B_freq[m]);
}
fprintf(fp_G,"Symol\tFreq_G\n");
for (m=0;m<256;m++)
{
fprintf(fp_G,"%d\t\t%.8f\n",m,G_freq[m]);
}
fprintf(fp_R,"Symol\tFreq_R\n");
for (m=0;m<256;m++)
{
fprintf(fp_R,"%d\t\t%.8f\n",m,R_freq[m]);
}
for(i=0;i<width;i++)//计算熵
{
if(abs(B_freq[i]>1e-10))
B_entropy=B_entropy-B_freq[i]*log(B_freq[i])/log(2.0);
if(abs(G_freq[i]>1e-10))
G_entropy=G_entropy-G_freq[i]*log(G_freq[i])/log(2.0);
if(abs(R_freq[i]>1e-10))
R_entropy=R_entropy-R_freq[i]*log(R_freq[i])/log(2.0);
}
printf("B基色的平均信息熵为%.8f比特/符号\n",B_entropy);
printf("G基色的平均信息熵为%.8f比特/符号\n",G_entropy);
printf("R基色的平均信息熵为%.8f比特/符号\n",R_entropy);
fclose(fp);//关闭文件
fclose(fp_B);
fclose(fp_G);
fclose(fp_R);
getchar();
return 0;
}