分析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<iostream>
#include<string.h>
#include<assert.h>
#include<math.h>
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文件:
在这里插入图片描述
输出的熵值:
在这里插入图片描述
概率分布图:
在这里插入图片描述

2、yuv文件:

代码:
#include<iostream>
#include<string.h>
#include<assert.h>
#include<math.h>
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文件:
在这里插入图片描述
输出的熵值:
在这里插入图片描述
概率分布图:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值