一、实验任务
分析rgb和yuv文件的三个通道的概率分布,并计算各自的熵(编程实现)。
注释:
- down.rgb和down.yuv两个文件的分辨率均为256*256。
- yuv为4:2:0采样空间。
二. 实验代码:
计算RGB
#include<iostream>
#include<math.h>
using namespace std;
int main()
{
unsigned char R[256*256] = { 0 }, G[256*256] = { 0 }, B[256*256] = { 0 },img[256*256*3] = { 0 };//定义R、G、B、img量
double Rp[256] = { 0 }, Gp[256] = { 0 }, Bp[256] = { 0 }; //定义R、G、B概率分量
double R2 = 0, G2 = 0, B2 = 0; //定义R、G、B的熵
FILE* fp = fopen("C:\\Users\\陈玥\\Desktop\\zuoye1\\down.rgb", "rb");
fread(img, sizeof(unsigned char), 256*256*3, fp);
fclose(fp);
for (int i = 0;i < 256*256; i++)
{
R[i] = img[3*i];
G[i] = img[3*i+1];
B[i] = img[3*i+2];
}
//分别统计R、G、B三通道的颜色强度级的频数
for (int i = 0; i < 256*256; i++)
{
Rp[R[i]]++;
Gp[G[i]]++;
Bp[B[i]]++;
}
//分别计算R、G、B三通道的256个颜色强度级的概率
for (int i = 0; i < 256; i++)
{
Rp[i] = Rp[i] / (256*256);
Gp[i] = Gp[i] / (256*256);
Bp[i] = Bp[i] / (256*256);
}
//建立概率文件
FILE* dr = fopen("C:\\Users\\陈玥\\Desktop\\zuoye1\\R.txt","w");//建立存放Y数据
FILE* dg = fopen("C:\\Users\\陈玥\\Desktop\\zuoye1\\G.txt","w");//建立存放U数据
FILE* db = fopen("C:\\Users\\陈玥\\Desktop\\zuoye1\\B.txt","w");//建立存放V数据
//将概率写入文件
for (int i = 0; i < 256; i++)
{
fprintf(dr, "%d\t%f\n", i, Rp[i]);
fprintf(dg, "%d\t%f\n", i, Gp[i]);
fprintf(db, "%d\t%f\n", i, Bp[i]);
}
//计算并输出熵
for (int i = 0; i < 256; i++)
{
if (Rp[i] != 0) { R2 += -Rp[i] * log(Rp[i]) / log(2.0); }
if (Gp[i] != 0) { G2 += -Gp[i] * log(Gp[i]) / log(2.0); }
if (Bp[i] != 0) { B2 += -Bp[i] * log(Bp[i]) / log(2.0); }
}
fprintf(dr,"Y的熵 = %f",R2);//输出B的熵
fprintf(dg,"U的熵 = %f",G2);//输出G的熵
fprintf(db,"V的熵 = %f",B2);//输出R的熵
return 0;
}
运行结果:
生成的rgb文件:
R:
G:
B:
计算YUV
程序实现:
#include<iostream>
#include<math.h>
using namespace std;
int main()
{
unsigned char Y[256*256] = { 0 }, U[256*256/4] = { 0 }, V[256*256/4] = { 0 },img[256*256*3] = { 0 };//定义Y、U、V、img量
double Yp[256] = { 0 }, Up[256] = { 0 }, Vp[256] = { 0 }; //定义Y、U、V概率分量
double Y2 = 0, U2 = 0, V2 = 0; //定义Y、U、V的熵
FILE* fp = fopen("C:\\Users\\陈玥\\Desktop\\zuoye1\\down.yuv", "rb");
fread(img, sizeof(unsigned char), 256*256*3, fp);
fclose(fp);
for (int i = 0; i < 256*256 ; i++)
{
Y[i] = img[i];
}
for (int i = 0;i < 256*256/4; i++)
{
U[i] = img[i+256*256];
V[i] = img[i+256*256*5/4];
}
//分别统计Y、U、V三通道的颜色强度级的频数
for (int i = 0; i < 256*256; i++)
{
Yp[Y[i]]++;
}
for (int i = 0; i < (256*256/4); i++)
{
Up[U[i]]++;
Vp[V[i]]++;
}
//分别计算Y、U、V三通道的256个颜色强度级的概率
for (int i = 0; i < 256; i++)
{
Yp[i] = Yp[i] / (256*256);
Up[i] = Up[i] / (256*256/4);
Vp[i] = Vp[i] / (256*256/4);
}
//建立概率文件
FILE* dy = fopen("C:\\Users\\陈玥\\Desktop\\zuoye1\\Y.txt","w");//建立存放Y数据
FILE* du = fopen("C:\\Users\\陈玥\\Desktop\\zuoye1\\U.txt","w");//建立存放U数据
FILE* dv = fopen("C:\\Users\\陈玥\\Desktop\\zuoye1\\V.txt","w");//建立存放V数据
//将概率写入文件
for (int i = 0; i < 256; i++)
{
fprintf(dy, "%d\t%f\n", i, Yp[i]);
fprintf(du, "%d\t%f\n", i, Up[i]);
fprintf(dv, "%d\t%f\n", i, Vp[i]);
}
//计算并输出熵
for (int i = 0; i < 256; i++)
{
if (Yp[i] != 0) { Y2 += -Yp[i] * log(Yp[i]) / log(2.0); }
if (Up[i] != 0) { U2 += -Up[i] * log(Up[i]) / log(2.0); }
if (Vp[i] != 0) { V2 += -Vp[i] * log(Vp[i]) / log(2.0); }
}
fprintf(dy,"Y的熵 = %f",Y2);//输出B的熵
fprintf(du,"U的熵 = %f",U2);//输出G的熵
fprintf(dv,"V的熵 = %f",V2);//输出R的熵
return 0;
}
运行结果:
生成的YUV文本文件:
Y:
U:
V:
**
三.实验结论
**
将文件导入到excel表格里可以观察到yuv分量的熵小于rgb分量的熵,去相关性更差。与理论结果符合。