作业要求:
对群里发的down.rgb和down.yuv分析三个通道的概率分布,并计算各自的熵。(编程实现)
两个文件的分辨率均为256*256,yuv为4:2:0采样空间,存储格式为:rgb文件按每个像素BGR分量依次存放;YUV格式按照全部像素的Y数据块、U数据块和V数据块依次存放。
实验思路:
1、将R、G、B三个分量存放于三个txt中
Y、U、V三个分量根据4:2:0的采样空间存放
2、算出rgb、yuv的各通道概率分布
3、计算rgb、yuv的熵,输出
实验代码:
- 计算RGB
#include <stdio.h>
#include <iostream>
#include <assert.h>
#include <string.h>
#include<math.h>
using namespace std;
int main()
{
FILE *fp, *rr, *gg, *bb;
fp=fopen("/Users/997xyq/Desktop/down.rgb","rb");
rr=fopen("/Users/997xyq/Desktop/R.txt","w");
gg=fopen("/Users/997xyq/Desktop/G.txt","w");
bb=fopen("/Users/997xyq/Desktop/B.txt","w");
unsigned char R[256*256]={0},G[256*256]={0},B[256*256]={0};//分量
double R_F[256]={0},G_F[256]={0},B_F[256]={0};//频率
double R_H=0,G_H=0,B_H=0;//熵
unsigned char s[256*256*3]={0};
fread(s,1,256*256*3,fp);
for(int i=0,j=0;i<256*256*3;i=i+3,j++)
{
B[j]=*(s+i);
G[j]=*(s+i+1);
R[j]=*(s+i+2);
}//把分量放到数组中
for(int i=0;i<256*256;i++)
{
R_F[R[i]]++;
G_F[G[i]]++;
B_F[B[i]]++;
}//频数
for(int i=0;i<256;i++)
{
R_F[i]=R_F[i]/(256*256);
G_F[i]=G_F[i]/(256*256);
B_F[i]=B_F[i]/(256*256);
}//概率
for(int i=0;i<256;i++)
{
fprintf(rr,"%d\t%f\n",i,R_F[i]);
fprintf(gg,"%d\t%f\n",i,G_F[i]);
fprintf(bb,"%d\t%f\n",i,B_F[i]);
}//写入txt
for(int i=0;i<256;i++)
{
if(R_F[i]!=0)
{
R_H += -R_F[i] * log(R_F[i])/log(double(2));
}
if(G_F[i]!=0)
{
G_H += -G_F[i] * log(G_F[i])/log(double(2));
}
if(B_F[i]!=0)
{
B_H += -B_F[i] * log(B_F[i])/log(double(2));
}
}//算熵
cout<<"R的熵为"<<R_H<<endl;
cout<<"G的熵为"<<G_H<<endl;
cout<<"B的熵为"<<B_H<<endl;
return 0;
}
熵结果:
2、计算YUV
#include <stdio.h>
#include <iostream>
#include <assert.h>
#include <string.h>
#include<math.h>
using namespace std;
int main()
{
FILE *fp, *yy, *uu, *vv;
fp=fopen("/Users/997xyq/Desktop/down.yuv","rb");
yy=fopen("/Users/997xyq/Desktop/Y.txt","w");
uu=fopen("/Users/997xyq/Desktop/U.txt","w");
vv=fopen("/Users/997xyq/Desktop/V.txt","w");
unsigned char Y[256*256]={0},U[256*256/4]={0},V[256*256/4]={0};//分量
double Y_F[256]={0},U_F[256]={0},V_F[256]={0};//频率
double Y_H=0,U_H=0,V_H=0;//熵
unsigned char s[98304]={0};
fread(s,1,98304,fp);
for(int i=0;i<65536;i++)
{
Y[i]=*(s+i);
}//把y分量放到数组中
for(int i=65536;i<81920;i++)
{
U[i-65536]=*(s+i);
}把u分量放到数组中
for(int i=81920;i<98304;i++)
{
V[i-81920]=*(s+i);
}把v分量放到数组中
for(int i=0;i<65535;i++)
{
Y_F[Y[i]]++;
}
for(int i=0;i<(65535/4);i++)
{
U_F[U[i]]++;
V_F[V[i]]++;
}
for(int i=0;i<256;i++)
{
Y_F[i]=Y_F[i]/(65535);
U_F[i]=U_F[i]/(65535/4);
V_F[i]=V_F[i]/(65535/4);
}//概率
for(int i=0;i<256;i++)
{
fprintf(yy,"%d\t%f\n",i,Y_F[i]);
fprintf(uu,"%d\t%f\n",i,U_F[i]);
fprintf(vv,"%d\t%f\n",i,V_F[i]);
}//写入txt
for(int i=0;i<256;i++)
{
if(Y_F[i]!=0)
{
Y_H += -Y_F[i] * log(Y_F[i])/log(double(2));
}
if(U_F[i]!=0)
{
U_H += -U_F[i] * log(U_F[i])/log(double(2));
}
if(V_F[i]!=0)
{
V_H += -V_F[i] * log(V_F[i])/log(double(2));
}
}//算熵
cout<<"Y的熵为"<<Y_H<<endl;
cout<<"U的熵为"<<U_H<<endl;
cout<<"V的熵为"<<V_H<<endl;
return 0;
}
结果:
excel画出概率分布图
结论:
1、yuv熵大于tgb的熵
2、rgb分布比yuv均匀