数据压缩(三)——R,G,B三分量概率分布

任务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

在这里插入图片描述
在这里插入图片描述

合图

在这里插入图片描述

各分量的熵

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值