数据压缩(三)读入RGB文件得到分量的概率分布图(用c实现)
程序员文章站
2022-03-23 11:25:01
...
题目:
读入一个24bitRGB文件(以down.rgb为例,其分辨率为256*256),输出该数据文件中R、G、B三个分量(各8bit表示)的概率分布示意图。
思考过程:
- 以”rb“形式打开RGB文件
24bit,256×256,可以用fopen语句。
FILE* fp = fopen("D:\\data\\down.rgb", "rb+");
- 读取RGB分量并保存到数组中
可以用fread语句把数据读入到指针或数组buffer中,结合RGB的排列形式,用循环把RGB三个分量分别放到已经建好的数组中。
fread(buffer, 1, w*h*3, fp);
for (int i = 0, j = 0; i < w * h * 3; i = i + 3, j++)
{
r[j] = *(buffer + i);
g[j] = *(buffer + i + 1);
b[j] = *(buffer + i + 2);//把RGB分量保存到数组中
}
- 计算频次
用了两个循环语句来计算频次,这样对我来说比较简单。一个循环来记0~255,一个循环记像素点总数。
for (int i = 0; i < 256; i++)//0~255
{
for (int j = 0; j < w * h; j++)
{
if (int(r[j]) == i) { frequency_r[i]++; }
}
}
- 由此得到概率
for (int i = 0; i < 256; i++)
{
frequency_r[i] = frequency_r[i] / double(w * h);
}
- 以”w“形式打开三个txt文件
使用了fopen语句
FILE* fp1 = fopen("D:\\data\\R_sat.txt", "w+");
- 把概率写入文件中
这里出现了问题,一开始使用的是fwrite语句,输出出了问题。后面在大佬的帮助下,改成了fprintf语句。
错误代码:
double* buffer_r = frequency_r;
fwrite(buffer_r, 1, w*h, fp1);
改正:
fprintf(fp1, "%-3d\t%-8f\n", i, frequency_r[i]);
最终完整代码:
#include<iostream>
#include<stdio.h>
using namespace std;
#pragma warning(disable : 4996)
unsigned char r[65536];
unsigned char g[65536];
unsigned char b[65536];//定义三个数组
int w = 256;
int h = 256;//定义width和height
double frequency_r[256] = { 0 };
double frequency_g[256] = { 0 };
double frequency_b[256] = { 0 };//定义RGB 的概率
int main()
{
FILE* fp = fopen("D:\\data\\down.rgb", "rb+");//以rb形式打开rgb文件
unsigned char buffer[196608];
fread(buffer, 1, 196608, fp);
for (int i = 0, j = 0; i < w * h * 3; i = i + 3, j++)
{
r[j] = *(buffer + i);
g[j] = *(buffer + i + 1);
b[j] = *(buffer + i + 2);//把RGB分量保存到数组中
}
for (int i = 0; i < 256; i++)//0~255
{
for (int j = 0; j < w * h; j++)
{
if (int(r[j]) == i) { frequency_r[i]++; }
}
}
for (int i = 0; i < 256; i++)//0~255
{
for (int j = 0; j < w * h; j++)
{
if (int(g[j]) == i) { frequency_g[i]++; }
}
}
for (int i = 0; i < 256; i++)//0~255
{
for (int j = 0; j < w * h; j++)
{
if (int(b[j]) == i) { frequency_b[i]++; }
}
}
for (int i = 0; i < 256; i++)
{
frequency_r[i] = frequency_r[i] / double(w * h);
frequency_g[i] = frequency_g[i] / double(w * h);
frequency_b[i] = frequency_b[i] / double(w * h);
}//计算RGB的概率分布和熵
FILE* fp1 = fopen("D:\\data\\R_sat.txt", "w+");
FILE* fp2 = fopen("D:\\data\\G_sat.txt", "w+");
FILE* fp3 = fopen("D:\\data\\B_sat.txt", "w+");//以w形式打开三个txt文件
fprintf(fp1, "Symbol\tFrequency\n");
fprintf(fp2, "Symbol\tFrequency\n");
fprintf(fp3, "Symbol\tFrequency\n");
for (int i = 0; i < 256; i++)
{
fprintf(fp1, "%-3d\t%-8f\n", i, frequency_r[i]); // 将数据输出到文件中
fprintf(fp2, "%-3d\t%-8f\n", i, frequency_g[i]); // 将数据输出到文件中
fprintf(fp3, "%-3d\t%-8f\n", i, frequency_b[i]); // 将数据输出到文件中
}
fclose(fp);
fclose(fp1);
fclose(fp2);
fclose(fp3);//关闭文件
return 0;
}