任务3:读入一个24bitRGB文件(以down.rgb为例,其分辨率为256*256),输出该数据文件中R、G、B三个分量(各8bit表示)的概率分布示意图。
(一)实验代码(错误版)
#include <iostream>
#include <fstream>
#define SIZE 65536
using namespace std;
int main()
{
ifstream iofile("D:\\0CUC\\digital_yasuo\\down.rgb", ios::binary);
ofstream outfileR("D:\\0CUC\\digital_yasuo\\R.txt", ios::trunc);
ofstream outfileG("D:\\0CUC\\digital_yasuo\\G.txt", ios::trunc);
ofstream outfileB("D:\\0CUC\\digital_yasuo\\B.txt", ios::trunc);
//输出文件头
outfileR << "symbol\tfreq" << endl;
outfileG << "symbol\tfreq" << endl;
outfileB << "symbol\tfreq" << endl;
if (!iofile)
{
cout << "error!" << endl;
exit(1);
}
unsigned char* R_i = new unsigned char[SIZE];
unsigned char* G_i = new unsigned char[SIZE];
unsigned char* B_i = new unsigned char[SIZE];
int R[256] = { 0 }, G[256] = { 0 }, B[256] = { 0 };//统计频率。取值为0-255,最后计算频次时的分母为width*height=65536
//文件读取复制
for (int i = 0; i < SIZE; i++)
{
iofile >> R_i[i];
R[int(R_i[i])]++;
iofile >> G_i[i];
G[int(G_i[i])]++;
iofile >> B_i[i];
B[int(B_i[i])]++;
}
for (int i = 0; i < 256; i++)
{
outfileR << i << "\t" << R[i] * 1.0 / SIZE << endl;
outfileG << i << "\t" << G[i] * 1.0 / SIZE << endl;
outfileB << i << "\t" << B[i] * 1.0 / SIZE << endl;
}
//关闭文件
iofile.close();
outfileR.close();
outfileG.close();
outfileB.close();
return 0;
}
(二)实验结果(错误版)
R
G
B
合图
(三)实验代码(纠正版)
原代码错误原因1
此段代码出错,应纠正为(虽然并不知道这两段代码有啥不同,但是记住以后二进制文件的读不要用>>就对了,在大佬帮助下发现第一种方法在13174个数时出错了):
原代码错误原因2
忘记计算各分量的熵。所以添加如下代码:
修正后的代码如下:
#include <iostream>
#include <fstream>
#define SIZE 65536
using namespace std;
int main()
{
ifstream iofile("D:\\0CUC\\digital_yasuo\\down.rgb", ios::binary);
ofstream outfileR("D:\\0CUC\\digital_yasuo\\R.txt", ios::trunc);
ofstream outfileG("D:\\0CUC\\digital_yasuo\\G.txt", ios::trunc);
ofstream outfileB("D:\\0CUC\\digital_yasuo\\B.txt", ios::trunc);
//输出文件头
outfileR << "symbol\tfreq" << endl;
outfileG << "symbol\tfreq" << endl;
outfileB << "symbol\tfreq" << endl;
if (!iofile)
{
cout << "error!" << endl;
exit(1);
}
unsigned char R_i[SIZE];
unsigned char G_i[SIZE];
unsigned char B_i[SIZE];
int R[256] = { 0 }, G[256] = { 0 }, B[256] = { 0 };//统计频率。取值为0-255,最后计算频次时的分母为width*height=65536
//文件读取复制
for (int i = 0; i < SIZE; i++)
{
iofile.read((char*)&B_i[i], sizeof(unsigned char));
B[int(B_i[i])]++;
iofile.read((char*)&G_i[i], sizeof(unsigned char));
G[int(G_i[i])]++;
iofile.read((char*)&R_i[i], sizeof(unsigned char));
R[int(R_i[i])]++;
}
//算熵
double entropyG = 0, entropyB = 0, entropyR = 0;
for (int i = 0; i < 256; i++)
{
double pG = G[i] / (double)SIZE;
if (pG != 0)
{
entropyG += pG * log(1 / pG) / log(2);
}
double pB = B[i] / (double)SIZE;
if (pB != 0)
{
entropyB += pB * log(1 / pB) / log(2);
}
double pR = R[i] / (double)SIZE;
if (pR != 0)
{
entropyR += pR * log(1 / pR) / log(2);
}
}
for (int i = 0; i < 256; i++)
{
outfileR << i << "\t" << R[i] / (double)SIZE << endl;
outfileG << i << "\t" << G[i] / (double)SIZE << endl;
outfileB << i << "\t" << B[i] / (double)SIZE << endl;
}
//关闭文件
iofile.close();
outfileR.close();
outfileG.close();
outfileB.close();
return 0;
}
(四)实验结果(纠正版)
B
G
R