对down.rgb和down.yuv分析三个通道的概率分布,并计算各自的熵。(编程实现)
本文采用 C++ 编写
rgb 文件中每个像素都按照 BGR 依次存放,则为BGRBGRBGRBGR…循环,由图像分辨率256 * 256可得,此 rgb 文件共有 256 * 256 * 3 = 196608个像素。
yuv 文件是 4:2:0 的采样空间,即每四个Y分量共用一个 UV 分量。
是基于平面模式进行存储。即先存储所有的 Y 分量,然后存储所有的 U 分量,最后 V 分量。
图片来源于网络
y分量所占为256 * 256 = 65536
u分量:
首:256 * 256 = 65536
尾:256 * 256 *(1+1/4)= 81920
v分量:
首:256 * 256 *(1+1/4)= 81920
尾:256 * 256 *(1+1/2)= 98304
#include
#include
#include
using namespace std;
//定义图像的分辨率
//256*256=65536
int height=256;
int wide=256;
int main()
{
//定义R、G、B分量
unsigned char R[65536]={
0};
unsigned char G[65536]={
0};
unsigned char B[65536]={
0};
//定义数量
double R_num[256]={
0};
double G_num[256]={
0};
double B_num[256]={
0};
//定义频率
double R_fre[256]={
0};
double G_fre[256]={
0};
double B_fre[256]={
0};
//定义RGB分量的熵
double R_shang=0;
double G_shang=0;
double B_shang=0;
//定义文件指针
//打开所给的RGB图像文件
FILE* image;
fopen_s(&image,"C:\\Users\\Zhao Zhuo\\Desktop\\down.rgb", "rb");
//定义文件RGB指针
FILE* Red;
FILE* Green;
FILE* Blue;
//定义最终存储数据的txt文档
fopen_s(&Red,"C:\\Users\\Zhao Zhuo\\Desktop\\Red.txt", "w");
fopen_s(&Green,"C:\\Users\\Zhao Zhuo\\Desktop\\Green.txt", "w");
fopen_s(&Blue,"C:\\Users\\Zhao Zhuo\\Desktop\\Blue.txt", "w");
//256*256*3=196608
unsigned char buffer[196608];
fread(buffer,sizeof(unsigned char),196608,image);
for(int i=0,j=0;i<196608;i=i+3,j++)
{
//按BGR顺序存储
//读取RGB分量到数组
B[j]=*(buffer+i);
G[j]=*(buffer+i+1);
R[j]=*(buffer+i+2);
}
//计算数量
for(int i=0;i<256;i++)
{
for(int j=0;j<65536;j++)
{
if(int(R[j]==i)){
R_num[i]++;}
if (int(G[j]==i)){
G_num[i]++;}
if (int(B[j]==i)){
B_num[i]++;}
}
}
//计算频率
for(int i=0;i<256;i++)
{
R_fre[i]=R_num[i]/(256*256);
B_fre[i]=B_num[i]/(256*256);
G_fre[i]=G_num[i]/(256*256);
}
//计算熵
for (int i=0;i<256;i++)
{
if(R_fre[i]!=0)
{
R_shang += -R_fre[i]*log(R_fre[i])/log(double(2));}
if(B_fre[i]!=0)
{
B_shang += -B_fre[i]*log(B_fre[i])/log(double(2));}
if(G_fre[i]!=0)
{
G_shang += -G_fre[i]*log(G_fre[i])/log(double(2));}
}
//输出
cout<<"R的熵为"<<R_shang<<endl;
cout<<"G的熵为"<<G_shang<< endl;
cout<<"B的熵为"<<B_shang<< endl;
//写入文件
for (int i=0;i<256;i++)
{
fprintf(Red,"%d\t%f\n",i,R_fre[i]);
fprintf(Green,"%d\t%f\n",i,G_fre[i]);
fprintf(Blue,"%d\t%f\n",i,B_fre[i]);
}
//关闭
fclose(image);
fclose(Red);
fclose(Green);
fclose(Blue);
system("pause");
return 0;
}
#include
#include
#include
using namespace std;
//定义图像的分辨率
//256*256=65536
int height=256;
int wide=256;
int main()
{
//定义Y、U、V分量
//256*256*1/4=16384
unsigned char Y[65536]={
0};
unsigned char U[16384]={
0};
unsigned char V[16384]={
0};
//定义数量
double Y_num[256]={
0};
double U_num[256]={
0};
double V_num[256]={
0};
//定义频率
double Y_fre[256]={
0};
double U_fre[256]={
0};
double V_fre[256]={
0};
//定义YUV分量的熵
double Y_shang=0;
double U_shang=0;
double V_shang=0;
//定义文件指针
//打开所给的YUV图像文件
FILE* image;
fopen_s(&image,"C:\\Users\\Zhao Zhuo\\Desktop\\down.yuv", "rb");
//定义文件YUV指针
FILE* Ym;
FILE* Um;
FILE* Vm;
//定义最终存储数据的txt文档
fopen_s(&Ym,"C:\\Users\\Zhao Zhuo\\Desktop\\Y.txt", "w");
fopen_s(&Um,"C:\\Users\\Zhao Zhuo\\Desktop\\U.txt", "w");
fopen_s(&Vm,"C:\\Users\\Zhao Zhuo\\Desktop\\V.txt", "w");
//256*256*(1+1/2)=98304
unsigned char buffer[98304];
fread(buffer,sizeof(unsigned char),98304,image);
//按YUV数据块顺序存储
for(int i=0;i<256*256;i=i+1)
{
//读取Y分量到数组
Y[i]=*(buffer+i);
}
for(int i=65536;i<81920;i=i+1)
{
//读取U分量到数组
U[i-65536]=*(buffer+i);
}
for(int i=81920;i<98304;i=i+1)
{
//读取V分量到数组
V[i-81920]=*(buffer+i);
}
//计算数量
for(int i=0;i<256*256;i++)
{
Y_num[Y[i]]++;
}
for(int i=0;i<16384;i++)
{
U_num[U[i]]++;
V_num[V[i]]++;
}
//计算频率
for(int i=0;i<256;i++)
{
Y_fre[i]=Y_num[i]/(256*256);
U_fre[i]=U_num[i]/(256*256/4);
V_fre[i]=V_num[i]/(256*256/4);
}
//计算熵
for (int i=0;i<256;i++)
{
if(Y_fre[i]!=0)
{
Y_shang += -Y_fre[i]*log(Y_fre[i])/log(double(2));}
if(U_fre[i]!=0)
{
U_shang += -U_fre[i]*log(U_fre[i])/log(double(2));}
if(V_fre[i]!=0)
{
V_shang += -V_fre[i]*log(V_fre[i])/log(double(2));}
}
//输出
cout<<"Y的熵为"<<Y_shang<<endl;
cout<<"U的熵为"<<U_shang<<endl;
cout<<"V的熵为"<<V_shang<<endl;
//写入文件
for(int i=0;i<256;i++)
{
fprintf(Ym,"%d\t%f\n",i,Y_fre[i]);}
for(int i=0;i<256;i++)
{
fprintf(Um,"%d\t%f\n",i,U_fre[i]);}
for(int i=0;i<256;i++)
{
fprintf(Vm,"%d\t%f\n",i,V_fre[i]);}
//关闭
fclose(image);
fclose(Ym);
fclose(Um);
fclose(Vm);
system("pause");
return 0;
}
将输出到桌面上的几个 txt 文件结果导入 excel 中,并绘制折线图观察概率分布。
由输出结果可以看到
两结果可相互验证