作业|分析RGB、YUV文件三个通道的概率分布,并计算各自的熵

一、实验目的

  • 对群里发的down.rgb和down.yuv分析三个通道的概率分布,并计算各自的熵。

二、文件相关参数

  • 两个文件的分辨率均为256*256
  • yuv为4:2:0采样空间
  • YUV格式按照全部像素的Y数据块、U数据块和V数据块依次存放
  • rgb文件按每个像素BGR分量依次存放

三、实验思路

  • 根据两种文件不同的存储特性将其分量进行频次统计计算熵值,参考网络教程,保存不同通道数据导入到matlab进行绘图。

四、实验记录

1、分析RGB文件

cpp代码

#include
#include
using namespace std;
int main()
{
     
    unsigned char* b = new unsigned char[256*256];
	unsigned char* g = new unsigned char[256*256];
	unsigned char* r = new unsigned char[256*256];//存储r、g、b分量
    unsigned char* img = new unsigned char[256*256*3]; //存储图像所有值
    double R[256]={
     0};double G[256]={
     0}; double B[256]={
     0};//r、g、b值出现次数
    double R_pro[256]={
     0};double G_pro[256]={
     0};double B_pro[256]={
     0};//r、g、b概率分布
    double R_h=0;double G_h=0;double B_h=0;//r、g、b熵

   //读取原文件内容
    FILE* fp1=fopen("/Users/hugo/Desktop/数据压缩/第一周/down.rgb","rb");
    if(fp1 == NULL)
        cout<<"错误读取"<<endl;
    fread(img,sizeof(unsigned char),256*256*3,fp1);
    fclose(fp1);

    //将原文件数值按照b、g、r写入
    for(int i=0;i<256*256;i++)
    {
     
        b[i]=img[3*i];
        g[i]=img[3*i+1];
        r[i]=img[3*i+2];
    }

    //统计概率分布
    for(int j=0;j<256*256;j++)
    {
     
        B[b[j]]++;
        G[g[j]]++;
        R[r[j]]++;
    }
    for(int k=0;k<256;k++)
    {
     
        B_pro[k]=B[k]/(256*256);
        G_pro[k]=G[k]/(256*256);
        R_pro[k]=R[k]/(256*256);
    }
    
    //计算熵值
    for(int l=0;l<256;l++)
    {
     
        if(B_pro[l] != 0)
            B_h=B_h +(-B_pro[l]*log(B_pro[l])/log(2));
         if(G_pro[l] != 0)
            G_h=G_h +(-G_pro[l]*log(G_pro[l])/log(2));           
        if(R_pro[l] != 0)
            R_h=R_h +(-R_pro[l]*log(R_pro[l])/log(2));
    }
    cout<<"B的熵值为:"<<B_h<<endl;
    cout<<"G的熵值为:"<<G_h<<endl;
    cout<<"R的熵值为:"<<R_h<<endl;
    
    //导出概率分布值
    FILE* dataB=fopen("/Users/hugo/Desktop/数据压缩/第一周/b.txt","w");
    FILE* dataG=fopen("/Users/hugo/Desktop/数据压缩/第一周/g.txt","w");
    FILE* dataR=fopen("/Users/hugo/Desktop/数据压缩/第一周/r.txt","w");
    for(int i=0;i<256;i++)
    {
     
        fprintf(dataB,"%d\t%f\n",i,B_pro[i]);
        fprintf(dataG,"%d\t%f\n",i,G_pro[i]);
        fprintf(dataR,"%d\t%f\n",i,R_pro[i]);
    }
    fclose(dataB);
    fclose(dataG);
    fclose(dataR);

}

熵值结果

  • B的熵值为:6.85686
  • G的熵值为:7.17846
  • R的熵值为:7.22955

导出结果

作业|分析RGB、YUV文件三个通道的概率分布,并计算各自的熵_第1张图片

概率分布

作业|分析RGB、YUV文件三个通道的概率分布,并计算各自的熵_第2张图片

软件截图


作业|分析RGB、YUV文件三个通道的概率分布,并计算各自的熵_第3张图片

2、分析YUV文件

cpp代码

#include
#include
using namespace std;
int main()
{
     
    unsigned char* y = new unsigned char[256*256];
	unsigned char* u = new unsigned char[256*256/4];
	unsigned char* v = new unsigned char[256*256/4];//存储y、u、v分量
    unsigned char* img = new unsigned char[256*256*3/2]; //存储图像所有值
    double Y[256]={
     0};double U[256]={
     0}; double V[256]={
     0};//y、u、v值出现次数
    double Y_pro[256]={
     0};double U_pro[256]={
     0};double V_pro[256]={
     0};//y、u、v概率分布
    double Y_h=0;double U_h=0;double V_h=0;//y、u、v熵

   //读取原文件内容
    FILE* fp1=fopen("/Users/hugo/Desktop/数据压缩/第一周/down.yuv","rb");
    if(fp1 == NULL)
        cout<<"错误读取"<<endl;
    fread(img,sizeof(unsigned char),256*256*1.5,fp1);
    fclose(fp1);

    //将原文件数值按照y、u、v写入
    for(int i=0;i<256*256;i++)
    {
     
        y[i]=img[i];
    }
    for(int i=0;i<256*256*0.25;i++)
    {
     
        u[i]=img[256*256+i];
        v[i]=img[256*256*5/4+i];
    }

    //统计概率分布
    for(int j=0;j<256*256;j++)
        Y[y[j]]++;
    for(int j=0;j<256*256*0.25;j++)
    {
     
        U[u[j]]++;
        V[v[j]]++;
    }
    for(int k=0;k<256;k++)
    {
     
        Y_pro[k]=Y[k]/(256*256);
        U_pro[k]=U[k]/(256*256*0.25);
        V_pro[k]=V[k]/(256*256*0.25);
    }
    
    //计算熵值
    for(int l=0;l<256;l++)
    {
     
        if(Y_pro[l] != 0)
            Y_h=Y_h +(-Y_pro[l]*log(Y_pro[l])/log(2));
         if(U_pro[l] != 0)
            U_h=U_h +(-U_pro[l]*log(U_pro[l])/log(2));           
        if(V_pro[l] != 0)
            V_h=V_h +(-V_pro[l]*log(V_pro[l])/log(2));
    }
    cout<<"Y的熵值为:"<<Y_h<<endl;
    cout<<"U的熵值为:"<<U_h<<endl;
    cout<<"V的熵值为:"<<V_h<<endl;
    
   //导出概率分布值
    FILE* dataY=fopen("/Users/hugo/Desktop/数据压缩/第一周/y.txt","w");
    FILE* dataU=fopen("/Users/hugo/Desktop/数据压缩/第一周/u.txt","w");
    FILE* dataV=fopen("/Users/hugo/Desktop/数据压缩/第一周/v.txt","w");
    for(int i=0;i<256;i++)
    {
     
        fprintf(dataY,"%d\t%f\n",i,Y_pro[i]);
        fprintf(dataU,"%d\t%f\n",i,U_pro[i]);
        fprintf(dataV,"%d\t%f\n",i,V_pro[i]);
    }
    fclose(dataY);
    fclose(dataU);
    fclose(dataV);

}

熵值结果

  • Y的熵值为:6.33182
  • U的熵值为:5.1264
  • V的熵值为:4.11314

导出结果

作业|分析RGB、YUV文件三个通道的概率分布,并计算各自的熵_第4张图片

概率分布

作业|分析RGB、YUV文件三个通道的概率分布,并计算各自的熵_第5张图片

软件截图


作业|分析RGB、YUV文件三个通道的概率分布,并计算各自的熵_第6张图片

五、参考学习

  • Matlab导入txt文件并画图
  • 用C/C++读取rgb格式文件数据并分析其概率分布

你可能感兴趣的:(作业)