作业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图像分量熵值。