数据压缩第三次作业
读入一个24bitRGB文件(以down.rgb为例,其分辨率为256*256),输出该数据文件中R、G、B三个分量(各8bit表示)的概率分布示意图和熵。
思路及实现过程
1.打开要读出的RGB文件,打开3个要输出的数据统计文件-fopen
2.创建内存空间-buffer malloc
3.将RGB数据从RGB文件中读出,并分别保存到3个数组中-fread
4.对数据进行处理-Count
(包括计算概率分布和熵,并将相应数据写入txt)
5.输出香农熵-printf
6.释放内存空间-free malloc
7.关闭文件-fclose
全部代码
#include <stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<math.h>
constexpr auto width = 256;
constexpr auto height = 256;
//函数调用:实现RGB图像数据统计,频率计算,求熵
void Count(unsigned char * Buff, double
*freq,FILE* sat,double *H)
{
int num[256] = { 0 };
for (int i = 0; i < 256; i++)
{
for (int j = 0; j < width * height; j++)
{
if (i == Buff[j])
{
num[i]++;
}
}
}
fprintf(sat, "symbol\tfreq\n");
for (int i = 0; i < 256; i++)
{
freq[i] = double(num[i]) / (width * height);
fprintf(sat, "%d\t%f\n", i, freq[i]);
if (freq[i] != 0)
{
*H = *H - freq[i] * log(freq[i]) / log(2);
}
}
}
int main(int argc, char* argv[])
{
FILE* rgbFile=NULL;
FILE* Bsat=NULL;
FILE* Gsat=NULL;
FILE* Rsat=NULL;
//打开rgb图像并创建txt
errno_t err;
err = fopen_s(&rgbFile,argv[1], "rb");
if (err == 0)
{
printf("打开文件成功!\n");
}
else printf("打开文件失败!\n");
err = fopen_s(&Rsat, "R_sat.txt", "w");
if (err == 0)
{
printf("打开R_sat.txt成功!\n");
}
else printf("打开R_sat.txt失败!\n");
err = fopen_s(&Gsat, "G_sat.txt", "w");
if (err == 0)
{
printf("打开G_sat.txt成功!\n");
}
else printf("打开G_sat.txt失败!\n");
err = fopen_s(&Bsat, "B_sat.txt", "w");
if (err == 0)
{
printf("打开B_sat.txt成功!\n");
}
else printf("打开B_sat.txt失败!\n");
//分配动态内存
unsigned char* buffer = NULL;
unsigned char* rBuff = NULL;
unsigned char* gBuff = NULL;
unsigned char* bBuff = NULL;
buffer = (unsigned char*)malloc(sizeof(unsigned char) * width * height *
3);
rBuff = (unsigned char*)malloc(sizeof(unsigned char) * width * height );
gBuff = (unsigned char*)malloc(sizeof(unsigned char) * width * height );
bBuff = (unsigned char*)malloc(sizeof(unsigned char) * width * height );
fread(buffer, sizeof(unsigned char), 3 * width * height, rgbFile);
//分成RGB三通道存储数据
int nr = 0;
int ng = 0;
int nb = 0;
for (int i = 0; i < 3 * width * height; i++)
{
if (i % 3 == 0)
{
bBuff[nb] = *(buffer + i);
nb++;
}
else if (i % 3 == 1)
{
gBuff[ng] = *(buffer + i);
ng++;
}
else if (i % 3 == 2)
{
rBuff[nr] = *(buffer + i);
nr++;
}
}
//计算频率和熵,同时将频率表存入相应txt文档
double freqR[256] = { 0 };
double freqG[256] = { 0 };
double freqB[256] = { 0 };
double HR = 0;
double HG = 0;
double HB = 0;
Count(rBuff, freqR,Rsat,&HR);
Count(gBuff, freqG,Gsat,&HG);
Count(bBuff, freqB,Bsat,&HB);
//输出香农熵
printf("H(R)=%f\n", HR);
printf("H(G)=%f\n", HG);
printf("H(B)=%f\n", HB);
free(buffer);
free(rBuff);
free(gBuff);
free(bBuff);
fclose(rgbFile);
fclose(Bsat);
fclose(Gsat);
fclose(Rsat);
return 0;
}
实验结果
- txt文本
- 香农熵
- Excel图表