读取分析RGB文件
程序员文章站
2022-07-14 21:54:42
...
作业3:读入一个24bitRGB文件(以down.rgb为例,其分辨率为256*256),输出该数据文件中R、G、B三个分量(各8bit表示)的概率分布示意图(类似下图)和熵。
提示:(用C或C++实现时),程序的流程为:
开辟3个width*height的unsigned char型数组;打开要读出的RGB文件(以“rb”方式打开),打开3个要输出的数据统计文件(以“w”方式打开,可命名为R_sat.txt等);将RGB数据从RGB文件中读出,并分别保存到3个数组中,期间计算数据的概率分布和熵,并将这些数据写入3个数据统计txt文件中。Txt文件的写入方式如下所示(每行的两个数据用tab分开)。在Excel里将这3个txt文件打开即可生成统计图。
代码如下:
#include "pch.h"
#include <iostream>
int main()
{
constexpr auto width = 256;
constexpr auto height = 256;
errno_t err;
FILE* fp; //设置一文件指针
FILE *fr, *fg, *fb;
if ((err = fopen_s(&fp, "down.rgb", "rb")) == 0)//打开rgb文件
printf("The file 'down.rgb' was opened\n");
else
printf("The file 'down.rgb' was not opened\n");
if ((err = fopen_s(&fr, "R_sat.txt", "w")) == 0)//打开三个要输入数据的统计文件
printf("The file 'R_sat.txt' was opened\n");
else
printf("The file 'R_sat.txt' was not opened\n");
if ((err = fopen_s(&fg, "G_sat.txt", "w")) == 0)
printf("The file 'G_sat.txt' was opened\n");
else
printf("The file 'G_sat.txt' was not opened\n");
if ((err = fopen_s(&fb, "B_sat.txt", "w")) == 0)
printf("The file 'B_sat.txt' was opened\n");
else
printf("The file 'B_sat.txt' was not opened\n");
unsigned char *buffer;//设置动态内存地址
buffer = (unsigned char*)malloc(sizeof(unsigned char)*width*height * 3);//分配动态内存
if (buffer == NULL)
{
printf("申请失败");
}
fread(buffer, sizeof(unsigned char), width*height*3, fp);//将rgb文件中的数据读至buffer指向的动态空间
unsigned char B[width*height] = { 0 };
unsigned char G[width*height] = { 0 };
unsigned char R[width*height] = { 0 };
int i;
int j;
/*for (i = 0; i < width*height; i++)
{
R[i] = *(buffer + 3*i) && 0x000000FF;
G[i] = *(buffer + 3*i) && 0x0000FF00;
B[i] = *(buffer + 3*i) && 0x00FF0000;
}*///用单片机的方法写崩了-__-||
for (i = 0; i < width*height; i++)
{
B[i] = *(buffer + 3 * i);
G[i] = *(buffer + 3 * i+1);
R[i] = *(buffer + 3 * i+2);
}
int numR[256] = { 0 };
double freqR[256] = { 0 };
for (i = 0; i < 256; i++)
{
for (j = 0; j < width*height; j++)
{
if (R[j] == i)
{
numR[i]++;
}
}
freqR[i] =double(numR[i]) / (width * height);
}
//printf("%f", freqR[1]);
int numG[256] = { 0 };
double freqG[256] = { 0 };
for (i = 0; i < 256; i++)
{
for (j = 0; j < width*height; j++)
{
if (G[j] == i)
{
numG[i]++;
}
}
freqG[i] = double(numG[i]) / (width * height);
}
int numB[256] = { 0 };
double freqB[256] = { 0 };
for (i = 0; i < 256; i++)
{
for (j = 0; j < width*height; j++)
{
if (B[j] == i)
{
numB[i]++;
}
}
freqB[i] =double(numB[i]) / (width * height);
}
//计算熵
double HR=0;
for (i = 0; i < 256; i++)
{
if (freqR[i] != 0)
{
HR = HR - freqR[i] *log(freqR[i]) / log(2);
}
}
double HG=0;
for (i = 0; i < 256; i++)
{
if (freqG[i] != 0)
{
HG = HG - freqG[i] * log(freqG[i]) / log(2);
}
}
double HB=0;
for (i = 0; i < 256; i++)
{
if (freqB[i] != 0)
{
HB = HB - freqB[i] * log(freqB[i]) / log(2);
}
}
printf("R的熵为:%f\n", HR);
printf("G的熵为:%f\n", HG);
printf("B的熵为:%f\n", HB);
fprintf(fr, "%s\t%s\n", "symbol", "frequent");
for (i = 0; i < 256; i++)
{
fprintf(fr, "%d\t%f\n", i, freqR[i]);
}
fprintf(fg, "%s\t%s\n", "symbol", "frequent");
for (i = 0; i < 256; i++)
{
fprintf(fg, "%d\t%f\n", i, freqG[i]);
}
fprintf(fb, "%s\t%s\n", "symbol", "frequent");
for (i = 0; i < 256; i++)
{
fprintf(fb, "%d\t%f\n", i, freqB[i]);
}
free(buffer);
fclose(fp);
fclose(fr);
fclose(fg);
fclose(fb);
system("pause");
return 0;
}
结果:
R分量概率分布
G分量概率分布
B分量概率分布
运行结果