数据压缩作业1——对down.rgb和down.yuv分析三个通道的概率分布,并计算各自的熵。

作业1:
2. 对群里发的down.rgb和down.yuv分析三个通道的概率分布,并计算各自的熵。(编程实现)两个文件的分辨率均为256*256,yuv为4:2:0采样空间,存储格式为:rgb文件按每个像素BGR分量依次存放;YUV格式按照全部像素的Y数据块、U数据块和V数据块依次存放。

RGB图像
代码思路
rbg:256×256×3=196608byte≈192kb
由于rgb图像存储形式是rgbrgbrgb……因此r、g、b的位置数据固定可通过简单除法完成统计。
将r、g、b分别设置指针,分配存储空间后通过for循环统计数量再分别写入文件。

实现结果

#include<iostream>
using namespace std;  

const int width = 256;   
const int height = 256;  

int main(void)
{
 FILE *prgb=NULL;  
 FILE *pR=NULL;  
 FILE *pG=NULL;
 FILE *pB=NULL;	//设置指针
 
 int err1;
 err1=fopen_s(&prgb,"F:\\数据压缩\\lab1\\down.rgb","rb"); 
 fopen_s(&pR,"F:\\数据压缩\\lab1\\R_result.txt","w"); 
 fopen_s(&pG,"F:\\数据压缩\\lab1\\G_result.txt","w");
 fopen_s(&pB,"F:\\数据压缩\\lab1\\B_result.txt","w"); //打开分量结果存储文件
 
 unsigned char *RGBbuf = NULL;
 RGBbuf=(unsigned char *)malloc(sizeof(unsigned char)*3*width*height);  //动态分配指针地址内存
 if(RGBbuf==NULL){printf("WRONG RGB_buffer!!\n");}
  
 fread(RGBbuf,sizeof(unsigned char),3*width*height,prgb);  
 
 unsigned char RR[width*height]={0};  
 unsigned char GG[width*height]={0};
 unsigned char BB[width*height]={0};
 
 int r=0;
 int g=0;
 int b=0;
 int i=0;
 for(i;i<3*width*height;i++) //将读出的各分量数据依次放入相应的数组
 {
  if(i%3==0)
  {
   BB[b]=*(RGBbuf+i);
   b++;
  }
  else if(i%3==1)
  {
   GG[g]=*(RGBbuf+i);
   g++;
  }
  else
  {
   RR[r]=*(RGBbuf+i);
   r++;
  }
 }
 
 double Bnum[256]={0};
 double Bre[256]={0};
 for(int j=0;j<256;j++) //统计各分量数据概率并写入txt文件
 {
  for(int k=0;k<width*height;k++)
  {
   if(j==BB[k])
    Bnum[j]++;
  }
  Bre[j]=Bnum[j]/(width*height);
  fprintf(pB,"%d\t%lf\n",j,Bre[j]);
 }

 double Gnum[256]={0};
 double Gre[256]={0};
 for(int j=0;j<256;j++)
 {
  for(int k=0;k<width*height;k++)
  {
   if(j==GG[k])
    Gnum[j]++;
  }
  Gre[j]=Gnum[j]/(width*height);
  fprintf(pG,"%d\t%lf\n",j,Gre[j]);
 }

 double Rnum[256]={0};
 double Rre[256]={0};
 for(int j=0;j<256;j++)
 {
  for(int k=0;k<width*height;k++)
  {
   if(j==RR[k])
    Rnum[j]++;
  }
  Rre[j]=Rnum[j]/(width*height);
  fprintf(pR,"%d\t%lf\n",j,Rre[j]);
 }

 double HR=0,HG=0,HB=0;
 for(int i=0;i<256;i++) //计算分量熵值
 {
  if(Rre[i]!=0)
  {
   HR=HR-Rre[i]*(log(Rre[i])/log(double(2)));
  }
  if(Gre[i]!=0)
  {
   HG=HG-Gre[i]*(log(Gre[i])/log(double(2)));
  }
  if(Bre[i]!=0)
  {
   HB=HB-Bre[i]*(log(Bre[i])/log(double(2)));
  }
 }
 printf("R的熵=%f\n",HR);
 printf("G的熵=%f\n",HG);
 printf("B的熵=%f\n",HB);
 
 free(RGBbuf);
 fclose(prgb);
 fclose(pR);
 fclose(pG);
 fclose(pB);
 system("pause");
 return 0;
}    

图表成果
在这里插入图片描述

在这里插入图片描述
yuv图像
代码思路
yuv:256×256×1.5=98,304byte=96kb
yuv图像以4:2:0形式储存,其中y分量:256×256,u和v分量均为:128×128。
与rgb图像相似,yuv图像的存储形式固定为YCbCr,因此将固定位置上的分量统计即可得出yuv各分量概率统计图。


#include<iostream>
using namespace std;  

const int width = 256;  
const int height = 256; 

int main(void)
{
	FILE *pyuv=NULL;
	FILE *pY;
	FILE *pU;
	FILE *pV;//设置指针

	fopen_s(&pyuv,"F:\\数据压缩\\lab1\\down.yuv","rb");
	fopen_s(&pY,"F:\\数据压缩\\lab1\\Y_result.txt","w");
	fopen_s(&pU,"F:\\数据压缩\\lab1\\U_result.txt","w");
	fopen_s(&pV,"F:\\数据压缩\\lab1\\V_result.txt","w");//打开各分量结果存储文件

	unsigned char *YUVbuf = (unsigned char *)malloc(sizeof(unsigned char) *1.5*width*height);  //动态分配指针地址内存
	if(YUVbuf==NULL){printf("WRONG YUVbuf!!\n");}
		
	fread(YUVbuf,sizeof(unsigned char),1.5*width*height,pyuv);//读取文件数据

	unsigned char YY[width*height]={0};
	unsigned char UU[width*height/4]={0};
	unsigned char VV[width*height/4]={0};//定义各分量数组

	for(int i=0,j=0;i<width*height;i++,j++)//将读出的各分量数据依次放入相应的数组
	{
		YY[j]=YUVbuf[i];
	}
	for(int i=width*height,j=0;i<width*height*1.25;i++,j++)
	{
		UU[j]=YUVbuf[i];
	}
	for(int i=width*height*1.25,j=0;i<width*height*1.5;i++,j++)
	{
		VV[j]=YUVbuf[i];
	}

	int y=0;
	int u=0;
	int v=0;
	double Ynum[256]={0};
	double Yre[256]={0};
	for(int j=0;j<width*height;j++)//统计各分量数据概率并写入txt文件
	{
		y=YY[j];
		Ynum[y]++;
	}
	for(int k=0;k<256;k++)
	{
		Yre[k]=Ynum[k]/(width*height);
		fprintf(pY,"%d\t%lf\n",k,Yre[k]);
	}

	double Unum[256]={0};
	double Ure[256]={0};
	for(int j=0;j<width*height/4;j++)
	{
		u=UU[j];
		Unum[u]++;
	}
	for(int k=0;k<256;k++)
	{
		Ure[k]=Unum[k]/(width*height/4);
		fprintf(pU,"%d\t%lf\n",k,Ure[k]);
	}

	double Vnum[256]={0};
	double Vre[256]={0};
	for(int j=0;j<width*height/4;j++)
	{
		v=VV[j];
		Vnum[v]++;
	}
	for(int k=0;k<256;k++)
	{
		Vre[k]=Vnum[k]/(width*height/4);
		fprintf(pV,"%d\t%lf\n",k,Vre[k]);
	}

	double HY=0,HU=0,HV=0;
	for(int i=0;i<256;i++)	//计算各分量熵值
	{
		if(Yre[i]!=0)
		{
			HY=HY-Yre[i]*(log(Yre[i])/log(double(2)));
		}
		if(Ure[i]!=0)
		{
			HU=HU-Ure[i]*(log(Ure[i])/log(double(2)));
		}
		if(Vre[i]!=0)
		{
			HV=HV-Vre[i]*(log(Vre[i])/log(double(2)));
		}
	}
	printf("Y的熵值=%f\n",HY);
	printf("U的熵值=%f\n",HU);
	printf("V的熵值=%f\n",HV);

	free(YUVbuf);
	fclose(pyuv);
	fclose(pY);
	fclose(pU);
	fclose(pV);
	system("pause");
	return 0;
}		

图表成果
在这里插入图片描述
在这里插入图片描述
对比分析
1、rgb图像各分量概率分布峰值距离接近,yuv图像各分量概率分布峰值y与uv距离较远,与分量存储形式一致;
2、rbg图像分量熵值大于yuv图像分量熵值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值