- 思路:本任务中分析rgb文件和yuv文件三个通道的概率分布并计算各自熵过程几乎相同,只是RGB和YUV文件的存储格式不一样。故我首先将三通道的值分别存储到三个数组中,再分别计算三个通道每个值出现的次数,然后分别计算三个通道每个值的概率分布,接着分别计算三个通道的熵。
至于画图,原来《数字音视频处理》课上一直采用MATLAB,所以我将三通道概率导出为TXT文件后,用MATLAB导入并绘图。
2.分析RGB文件代码
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
#include<string>
#include <iostream>
using namespace std;
int main(void)
{
FILE* fp1 = fopen("down.rgb", "rb");
FILE* rgb_pr = fopen("rgb.txt", "w");
unsigned char* buffer_RGB = new unsigned char[256 * 256 * 3];
unsigned char* buffer_R = new unsigned char[256 * 256];
unsigned char* buffer_G = new unsigned char[256 * 256];
unsigned char* buffer_B = new unsigned char[256 * 256];
double R[256] = { 0 }, G[256] = { 0 }, B[256] = { 0 };
double* R_pr = new double[256]; double G_pr[256] = { 0 }, B_pr[256] = { 0 };
fread(buffer_RGB, sizeof(unsigned char), 256* 256*3, fp1);
fclose(fp1);
int j = 0;
/*将三通道的值分别存储到三个数组中*/
for (int i = 0; i <256 * 256 * 3; i=i+3)
{
buffer_B[j] = buffer_RGB[i];
buffer_G[j] = buffer_RGB[i+1];
buffer_R[j] = buffer_RGB[i+2];
j++;
}
/*分别计算三个通道每个值出现的次数*/
for (int i = 0; i < 256 * 256; i = i++)
{
R[buffer_R[i]]++;
G[buffer_G[i]]++;
B[buffer_B[i]]++;
}
/*分别计算三个通道每个值的概率分布*/
for (int i = 0; i < 256; i = i++)
{
R_pr[i]=R[i]/(256*256);
G_pr[i] = G[i] / (256 * 256);
B_pr[i] = B[i] / (256 * 256);
}
/*分别计算三个通道的熵*/
double H_R = 0, H_G = 0, H_B = 0;
for (int i = 0; i < 256;i++)
{
if (R_pr[i] != 0)
H_R = H_R + (-R_pr[i]) * log(R_pr[i]) / log(2);
if (G_pr[i] != 0)
H_G = H_G + (-G_pr[i]) * log(G_pr[i]) / log(2);
if (B_pr[i] != 0)
H_B = H_B + (-B_pr[i]) * log(B_pr[i]) / log(2);
}
cout << "R的熵为:" << H_R << endl;
cout << "G的熵为:" << H_G << endl;
cout << "B的熵为:" << H_B << endl;
fprintf(rgb_pr, "红色\t绿色\t蓝色\n");
for (int i = 0; i < 256; i++)
{
fprintf(rgb_pr, "%f\t%f\t%f\n", R_pr[i], G_pr[i], B_pr[i]);
}
fclose(rgb_pr);
return 0;
}
实验结果:
3.分析YUV文件代码
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string>
using namespace std;
int main(void)
{
FILE* fp1 = fopen("down.yuv", "rb");
FILE* yuv_pr = fopen("yuv.txt", "w");
unsigned char* buffer_yuv = new unsigned char[256 * 256 * 1.5];
fread(buffer_yuv, sizeof(char), 256 * 256 * 1.5, fp1);
unsigned char* buffer_y = new unsigned char[256 * 256];
unsigned char* buffer_u = new unsigned char[256 * 256*0.25];
unsigned char* buffer_v = new unsigned char[256 * 256*0.25];
double y[256] = { 0 }, u[256] = { 0 }, v[256] = { 0 };
double y_pr[256] = { 0 }, u_pr[256] = { 0 }, v_pr[256] = { 0 };
fclose(fp1);
/*将三通道的值分别存储到三个数组中*/
for (int i = 0,j=0; i < 256 * 256 ; i++,j++)
{
buffer_y[j] = buffer_yuv[i];
}
for (int i = 256 * 256,j=0; i < 256 * 256+256*256*0.25; i++,j++)
{
buffer_u[j] = buffer_yuv[i];
}
for (int i = 256 * 256 + 256 * 256 * 0.25,j=0; i < 256 * 256 + 256 * 256 * 0.25 + 256 * 256 * 0.25; i++,j++)
{
buffer_v[j] = buffer_yuv[i];
}
/*分别计算三个通道每个值出现的次数*/
int a = 0,b =0, c = 0;
for (int i = 0; i < 256*256; i = i++)
{
a=buffer_y[i];
y[a]++;
}
for (int i = 0; i < 256*256*0.25; i = i++)
{
b = buffer_u[i];
u[b]++;
c = buffer_v[i];
v[c]++;
}
/*分别计算三个通道每个值的概率分布*/
for (int i = 0; i < 256; i = i++)
{
y_pr[i] = y[i] / (256 * 256);
}
for (int i = 0; i < 256; i = i++)
{
u_pr[i] = u[i] / (256 * 256*0.25);
v_pr[i] = v[i] / (256 * 256*0.25);
}
double H_Y = 0, H_U = 0, H_V = 0;
for (int i = 0; i < 256; i = i++)
{
if (y_pr[i] != 0)
H_Y = H_Y + (-y_pr[i]) * log(y_pr[i]) / log(2);
if (u_pr[i] != 0)
H_U = H_U + (-u_pr[i]) * log(u_pr[i]) / log(2);
if (v_pr[i] != 0)
H_V = H_V + (-v_pr[i]) * log(v_pr[i]) / log(2);
}
cout << "Y的熵为:" << H_Y<< endl;
cout << "U的熵为:" << H_U << endl;
cout << "V的熵为:" << H_V << endl;
fprintf(yuv_pr, "Y\tU\tV\n");
for (int i = 0; i < 256; i++)
{
fprintf(yuv_pr, "%f\t%f\t%f\n", y_pr[i], u_pr[i], v_pr[i]);
}
fclose(yuv_pr);
return 0;
}
实验结果:
4.分析总结
由实验结果可知,yuv文件三通道的熵均小于rgb文件三通道的熵,而由matlab做出的图可知YUV文件三通道分布更不均匀,其熵更小,所以两者相印证。