分析目标文件rgb和yuv三个通道的概率分布,并计算各自的熵
程序员文章站
2022-05-28 14:27:39
...
对分析rgb和yuv三个通道的概率分布,并计算各自的熵
实验目的:
- 对目标文件down.rgb和down.yuv进行三个通道概率分布分析,并计算各自的熵。(编程实现)
- 两个文件的分辨率均为256*256,yuv为4:2:0采样空间,存储格式为:rgb文件按每个像素BGR分量依次存放;YUV格式按照全部像素的Y数据块、U数据块和V数据块依次存放。
实验过程:
- 编写代码,分别读取rgb文件像素值,写入txt文件,计并算出对应的熵值。
RGB:
#include <stdio.h>
#include <cmath>
#include <iostream>
#include"iomanip"
using namespace std;
int main()
{int width=256;
int height=256;
int image_size=width*height;
int i,j=0;
double B[257]={0};
double G[257]={0};
double R[257]={0};
double HB=0,HG=0,HR=0;
FILE *fp;
FILE *fp_B,*fp_G,*fp_R;//设置文件指针
fopen_s(&fp,"C:\\Users/Fans/Desktop/数据压缩/down.rgb","rb");
fopen_s(&fp_B,"C:\\Users/Fans/Desktop/数据压缩/down_b_p.txt","wb+");
fopen_s(&fp_G,"C:\\Users/Fans/Desktop/数据压缩/down_g_p.txt","wb+");
fopen_s(&fp_R,"C:\\Users/Fans/Desktop/数据压缩/down_r_p.txt","wb+");
unsigned char* RGBBbuffer;
RGBBbuffer=new unsigned char[image_size*3];
fread(RGBBbuffer, sizeof(unsigned char),image_size*3, fp);
cout.setf(ios::fixed);//位数不够自动补0(若需要自动补0,在cout之前进行补0的定义,cout中加入“<<fixed”)
for(j=0;j<image_size;j++)
{
for(i=0;i<=256;i++)
{
if(RGBBbuffer[3*j]==i)
B[i]=B[i]+1;
}
}
//B的像素值分布概率
for(j=0;j<image_size;j++)
{
for(i=0;i<=256;i++)
{
if(RGBBbuffer[3*j+1]==i)
G[i]=G[i]+1;
}
}
//G的像素值分布概率
for(j=0;j<image_size;j++)
{
for(i=0;i<=256;i++)
{
if(RGBBbuffer[3*j+2]==i)
R[i]=R[i]+1;
}
}//R的像素值分布概率
cout<<"像素值"<<" "<< "B概率"<<" "<< "G概率"<<" "<< "R概率"<<endl;
fprintf(fp_B,"B概率\t");
fprintf(fp_G,"G概率\t");
fprintf(fp_R,"R概率\t");
for(i=0;i<=256;i++)
{
B[i]=B[i]/image_size;
G[i]=G[i]/image_size;
R[i]=R[i]/image_size;
cout<<i<<" ";
cout << fixed <<setprecision(4)<<B[i]<<" "<< G[i]<<" "<< R[i]<<endl;
fprintf(fp_B,"%f ",B[i]);
fprintf(fp_G,"%f ",G[i]);
fprintf(fp_R,"%f ",R[i]);
//将分量概率分布写入文件夹
if(B[i]!=0.0)
{ HB+=B[i]*(log(1/B[i])/log(2.0));}
if(G[i]!=0.0)
{ HG+=G[i]*log(1/G[i])/log(2.0);}
if(R[i]!=0.0)
{HR+=R[i]*log(1/R[i])/log(2.0);}//计算对应熵值
}
cout<<"熵"<<" B: "<<fixed <<setprecision(4)<<HB<<" G: "<<HG<<" R: "<<HR<<endl;
fclose(fp); //记得用完关闭文件
fclose(fp_B);
fclose(fp_G);
fclose(fp_R);
system("PAUSE");
return 0;
}
- 编写代码,计算得到rgb的熵结果如下
- 将txt文件导入excel,画出rgb分量概率分布。
YUV:
#include <stdio.h>
#include <iostream>
#include"iomanip"
using namespace std;
int main()
{int width=256;
int height=256;
int image_size=width*height;
int size=98304;
int i,j=0;
double Y[257]={0};
double U[257]={0};
double V[257]={0};
double HY=0,HU=0,HV=0;
FILE *fp;
FILE *fp_Y;
FILE *fp_U;
FILE *fp_V;//设置文件指针
fopen_s(&fp,"C:\\Users/Fans/Desktop/数据压缩/down.yuv","rb");
fopen_s(&fp_Y,"C:\\Users/Fans/Desktop/数据压缩/down_yuv_p.txt","wb+");
fopen_s(&fp_U,"C:\\Users/Fans/Desktop/数据压缩/down_u_p.txt","wb+");
fopen_s(&fp_V,"C:\\Users/Fans/Desktop/数据压缩/down_v_p.txt","wb+");
unsigned char* RGBBbuffer;
RGBBbuffer=new unsigned char[size];
fread(RGBBbuffer, sizeof(unsigned char),size, fp);
cout.setf(ios::fixed);//位数不够自动补0(若需要自动补0,在cout之前进行补0的定义,cout中加入“<<fixed”)
for(j=0;j<image_size;j++)
{
for(i=0;i<=256;i++)
{
if(RGBBbuffer[j]==i)
Y[i]=Y[i]+1;
}
}
//Y的像素值分布概率
for(j=image_size;j<image_size*5/4;j++)
{
for(i=0;i<=256;i++)
{
if(RGBBbuffer[j]==i)
U[i]=U[i]+1;
}
}
//U的像素值分布概率 for(j=image_size*5/4;j<image_size*3/2;j++)
{
for(i=0;i<=256;i++)
{
if(RGBBbuffer[j]==i)
V[i]=V[i]+1;
}
}//V的像素值分布概率
cout<<"像素值"<<" "<< "Y概率"<<" "<< "U概率"<<" "<< "V概率"<<endl;
fprintf(fp_Y,"Y概率\t");
fprintf(fp_U,"U概率\t");
fprintf(fp_V,"V概率\t");
for(i=0;i<=256;i++)
{
Y[i]=Y[i]/image_size;
U[i]=4*U[i]/image_size;
V[i]=4*V[i]/image_size;
cout<<i<<" ";
cout << fixed <<setprecision(4)<<Y[i]<<" "<< U[i]<<" "<< V[i]<<endl;
fprintf(fp_Y,"%f ",Y[i]);
fprintf(fp_U,"%f ",U[i]);
fprintf(fp_V,"%f ",V[i]);
if(Y[i]!=0.0)
{ HY+=Y[i]*(log(1/Y[i])/log(2.0));}
if(U[i]!=0.0)
{ HU+=U[i]*log(1/U[i])/log(2.0);}
if(V[i]!=0.0)
{HV+=V[i]*log(1/V[i])/log(2.0);}
}
cout<<"熵"<<" Y: "<<fixed <<setprecision(4)<<HY<<" U: "<<HU<<" V: "<<HV<<endl;
fclose(fp); //记得用完关闭文件
fclose(fp_Y);
fclose(fp_U);
fclose(fp_V);
system("PAUSE");
return 0;
}
- 编写代码,计算得到yuv的熵结果如下
- 将txt文件导入excel,画出yuv分量概率分布。
实验结果分析 - RGB三个通道分量的概率分布比YUV更平均,且RUV的熵总体大于YUV分量,则具有更好的去相关性。