欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

数据压缩作业三2020.03.24

程序员文章站 2022-07-14 21:56:24
...

读入一个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<bits/stdc++.h>
 using namespace std;  

int Height = 256;
int Width = 256;

int main()
{
	unsigned char R[65536]={0};
	unsigned char G[65536]={0};
	unsigned char B[65536]={0};//开辟三个width*height的unsigned char型数组
	FILE *file;
	file=fopen( "down.rgb", "rb");
	if(file==NULL) {
		cout<<"read error"<<endl;
	}else{
		cout<<"success"<<endl;
	}
	unsigned char buffer[196608];
	fread(buffer, 1,196608, file);//读出文件的像素
	int b=0; int g=0; int r=0; 	
	for(int i=0;i<196608;i++)
	{
		if(i%3==0){
			B[b]=buffer[i];
			b++;
		}else if(i%3==1){
			G[r]=buffer[i];
			r++;
		}else{
			R[g]=buffer[i];
			g++;
		}
	}//RGB保存各自数组
	
	double fR[256]={0};
	double fG[256]={0};
	double fB[256]={0};
	for (int i = 0; i < 256; i++)
	{	int x=0;
		for (int j = 0; j < Width*Height; j++)
		{
			if (R[j]==i){
				x++;
			}	
		}
		fR[i]=double(x)/double(Width)/double(Height);
	}
	for (int i = 0; i < 256; i++)
	{
		int y=0;
		for (int j = 0; j < Width*Height; j++)
		{
			if (G[j]==i){
				y++;
			}	
		}
		fG[i]=double(y)/double(Width)/double(Height);
	}
	for (int i = 0; i < 256; i++)
	{
		int z=0;
		for (int j = 0; j < Width*Height; j++)
		{
			if (B[j]==i){
				z++;
			}	
		}
		fB[i]=double(z)/double(Width)/double(Height);
	}//算出RGB的概率分布
	
	double sR = 0;
	double sG = 0;
	double sB = 0;
	for (int i = 0; i < 256; i++)
	{
			if (fR[i] != 0){
				sR += -fR[i]*log(fR[i]) / log(2);
			}
	}
	for (int i = 0; i < 256; i++)
	{
			if (fG[i] != 0){
			sG += -fG[i] * log(fG[i]) / log(2);
			}
	}
	for (int i = 0; i < 256; i++)
	{
			if (fB[i] != 0){
			sB += -fB[i] * log(fB[i]) / log(2);
			}
	}
	cout << "R的熵" << sR << endl;
	cout << "G的熵" << sG << endl;
	cout << "B的熵" << sB << endl;//计算熵

	FILE* R_sat;
	FILE* G_sat;
	FILE* B_sat;
	R_sat=fopen("R_sat.txt", "w");
	G_sat=fopen("G_sat.txt", "w");
	B_sat=fopen("B_sat.txt", "w");
	fprintf(R_sat, "symol\t freq\n");
	for (int i = 0; i < 256; i++)
	{
		fprintf(R_sat, "%d\t%f\n", i, fR[i]);
	}

    fprintf(G_sat, "symol\t freq\n");
	for (int i = 0; i < 256; i++)
	{
		fprintf(G_sat, "%d\t%f\n", i, fG[i]);
	}

   fprintf(B_sat, "symol\t freq\n");
	for (int i = 0; i < 256; i++)
	{
		fprintf(B_sat, "%d\t%f\n", i, fB[i]);
	}//输出三个TXT

	fclose(file);
	fclose(R_sat);
	fclose(G_sat);
	fclose(B_sat);
	return 0;
	}
	

结果
数据压缩作业三2020.03.24
数据压缩作业三2020.03.24
数据压缩作业三2020.03.24
遇到的问题:
1.读出写入函数的使用不熟练,对RGB不理解,不知道为什么取值0-255
2.设置的中间参数太多,思路不太清楚
RGB保存各自数组的部分,后来看同学代码发现可以不设rgb,循环时i=i+3,G[i]=buffuer[i],B[i]=buffuer[i+1],R[i]=buffuer[i+2]就可以
3.循环考虑不周全
算出RGB的概率分布部分,用于计数的xyz一开始在循环外定义,统计完一个灰度之后没有归零,导致计算出的熵在60-70。