分析rgb和yuv文件三个通道的概率分布并计算各自的熵

数据压缩第一次 作业2

一、作业要求:

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

二、解决思路:

用C++编程实现,根据两种文件的不同存储形式,统计出R,G,B和Y,U,V在每个点的频次,计算概率 ,然后将计算出的结果写入txt文件,计算熵输出,用matlab绘制概率分布图。

三、程序代码及结果

1、rgb文件:

代码:

#include
#include
#include
#include
using namespace std;

int main()
{
     
	unsigned char R[256*256]={
     0},G[256*256]={
     0},B[256*256]={
     0};
	unsigned char pic[256*256*3]={
     0}; 
	double Rf[256]={
     0},Gf[256]={
     0},Bf[256]={
     0};//频次
	double Rp[256]={
     0},Gp[256]={
     0},Bp[256]={
     0};//概率分布
	double Rh=0;double Gh=0;double Bh=0;//熵

	FILE * fp1=fopen("down.rgb","rb");
	fread(pic,1,256*256*3,fp1);

	//读取r,g,b分量
	for(int i=0;i<256*256;i++)
    {
     
        B[i]=pic[3*i];
        G[i]=pic[3*i+1];
        R[i]=pic[3*i+2];
    }

	//统计频次
	for(int j=0;j<256*256;j++)
    {
     
        Rf[R[j]]++;
        Gf[G[j]]++;
        Bf[B[j]]++;
    }
	
	//计算概率
	for(int k=0;k<256;k++)
    {
     
        Rp[k]=Rf[k]/(256*256);
        Gp[k]=Gf[k]/(256*256);
        Bp[k]=Bf[k]/(256*256);
    }
	
	//导出数值
	FILE * r_out=fopen("r.txt","w");
    FILE * g_out=fopen("g.txt","w");
    FILE * b_out=fopen("b.txt","w");

	for(int m=0;m<256;m++)
        {
     
            fprintf(r_out,"%d\t%f\n",m,Rp[m]);
            fprintf(g_out,"%d\t%f\n",m,Gp[m]);
            fprintf(b_out,"%d\t%f\n",m,Bp[m]);
        }

	//计算熵
	 for(int n=0;n<256;n++)
    {
     
        if(Rp[n] != 0)
            Rh=Rh +(-Rp[n]*log(Rp[n])/log(double(2)));
        if(Gp[n] != 0)
            Gh=Gh +(-Gp[n]*log(Gp[n])/log(double(2)));           
        if(Bp[n] != 0)
            Bh=Bh +(-Bp[n]*log(Bp[n])/log(double(2)));
    }

	 cout<<"R的熵为"<<Rh<<endl; 
	 cout<<"G的熵为"<<Gh<<endl;
	 cout<<"B的熵为"<<Bh<<endl;

	 system("pause");
	 return 0;
}

结果:

生成的txt文件:
分析rgb和yuv文件三个通道的概率分布并计算各自的熵_第1张图片
输出的熵值:
分析rgb和yuv文件三个通道的概率分布并计算各自的熵_第2张图片
概率分布图:
分析rgb和yuv文件三个通道的概率分布并计算各自的熵_第3张图片

2、yuv文件:

代码:

#include
#include
#include
#include
using namespace std;
int main()
{
     
	unsigned char Y[256*256]={
     0},U[256*256]={
     0},V[256*256]={
     0};
	unsigned char pic[256*256*3]={
     0}; 
	double Yf[256]={
     0},Uf[256]={
     0},Vf[256]={
     0};//频次
	double Yp[256]={
     0},Up[256]={
     0},Vp[256]={
     0};//概率分布
	double Yh=0;double Uh=0;double Vh=0;//熵

	FILE * fp2=fopen("down.yuv","rb");
	fread(pic,1,256*256*3,fp2);

	//读取y,u,v分量
	for(int i=0;i<256*256;i++)
    {
     
        Y[i]=pic[i];
    }

	for(int i=0;i<256*256/4;i++)
    {
     
        U[i]=pic[256*256+i];
        V[i]=pic[256*256+256*256/4+i];
    }

	//统计频次
	for(int i=0;i<256*256;i++)
    {
     
        Yf[Y[i]]++;
       
    }
	for(int i=0;i<256*256/4;i++)
	{
     
		Uf[U[i]]++;
        Vf[V[i]]++;
	}

	//计算概率
	for(int k=0;k<256;k++)
    {
     
        Yp[k]=Yf[k]/(256*256);
        Up[k]=Uf[k]/(256*256*0.25);
        Vp[k]=Vf[k]/(256*256*0.25);
    }
	
	//导出数值
	FILE * y_out=fopen("y.txt","w");
    FILE * u_out=fopen("u.txt","w");
    FILE * v_out=fopen("v.txt","w");

	for(int m=0;m<256;m++)
        {
     
            fprintf(y_out,"%d\t%f\n",m,Yp[m]);
            fprintf(u_out,"%d\t%f\n",m,Up[m]);
            fprintf(v_out,"%d\t%f\n",m,Vp[m]);
        }

	//计算熵
	 for(int n=0;n<256;n++)
    {
     
        if(Yp[n] != 0)
            Yh=Yh +(-Yp[n]*log(Yp[n])/log(double(2)));
        if(Up[n] != 0)
            Uh=Uh +(-Up[n]*log(Up[n])/log(double(2)));           
        if(Vp[n] != 0)
           Vh=Vh +(-Vp[n]*log(Vp[n])/log(double(2)));
    }

	 cout<<"Y的熵为"<<Yh<<endl; 
	 cout<<"U的熵为"<<Uh<<endl;
	 cout<<"V的熵为"<<Vh<<endl;

	 system("pause");
	 return 0;
}

结果:

生成的txt文件:
在这里插入图片描述
输出的熵值:
分析rgb和yuv文件三个通道的概率分布并计算各自的熵_第4张图片
概率分布图:
分析rgb和yuv文件三个通道的概率分布并计算各自的熵_第5张图片

你可能感兴趣的:(数据压缩)