分析rgb文件和yuv文件概率及各自的熵

本文档详细介绍了对RGB和YUV文件的概率分布及信息熵进行编程分析的过程,包括实验目的、实验流程、实验代码和实验分析。通过对256*256分辨率的down.rgb和down.yuv文件进行分析,发现RGB文件的概率分布更均匀,导致其熵大于YUV文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

编程实现对rgb和yuv的概率及信息熵的分析

*已知文件down.rgb和down.yuv两个文件

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

注:
数字电视系统基于三基色原理工作,图像源把彩色场景或图像转换为**红(R)、绿(G)和蓝(B)**三个模拟基色视频信号,将这三个基色信号数字化后,经种种处理,传送给终端。

**YUV(亦称YCrCb)**是被欧洲电视系统所采用的一种颜色编码方法(属于PAL)。其中“Y”表示明亮度(Luminance或Luma),也就是灰阶值;而“U”和“V”表示的则是色度(Chrominance或Chroma)。
与RGB视频信号传输相比,它最大的优点在于只需占用极少的带宽(RGB要求三个独立的视频信号同时传输)。
在水平和垂直方向上,两个色差信号取样点数,都减少到亮度信号取样点数的一半,即4个亮度信号取样点,对应两个色差信号的各一个取样点,称为4:2:0格式

一、实验目的

已知文件down.rgb和down.yuv两个文件,通过编程分析二者的三个通道的概率分布,并计算各自的熵。

二、实验流程

  1. 打开、创建所需文件

  2. 定义文件读取、存储数组

  3. 计算三通道数值的出现概率

  4. 定义并求解三通道信源熵
    在这里插入图片描述

  5. 将数据导入matlab,绘制概率分布图

三、实验代码

1.RGB代码

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <cmath>

using namespace std;

int main()
{

	int w = 256;
	int h = 256;
	int fileLength = w * h * 3;

	//打开、创建所需文件
	FILE* file = fopen("down.rgb", "rb");

	//动态分配地址
	unsigned char* dataArray = (unsigned char*)malloc(sizeof(unsigned char) * fileLength);
	unsigned char* r = (unsigned char*)malloc(w * h * sizeof(unsigned char));
	unsigned char* g = (unsigned char*)malloc(w * h * sizeof(unsigned char));
	unsigned char* b = (unsigned char*)malloc(w * h * sizeof(unsigned char));

	//读取文件
	fread(dataArray, sizeof(unsigned char), fileLength, file);

	//定义不同颜色通道计数
	int k = 0;
	int m = 0;  //b
	int n = 0;  //g
	int p = 0;  //r

	//定义参照数组跟三通道计数数组
	unsigned char item[256];
	double countR[256];
	double countG[256];
	double countB[256];
	for (int i = 0; i < 256; i++)
	{
		item[i] = (unsigned char)i;
		countR[i] = 0;
		countG[i] = 0;
		countB[i] = 0;
	}

	//分离RGB通道并对各通道的灰度值出现次数计数
	for (int i = 0; i < fileLength; i++)
	{
		if (i % 3 == 0)
		{
			b[m] = dataArray[i];
			while (b[m] != item[k])
			{
				k++;
			}
			countB[k]++;
			k = 0;
			m++;
		}
		else if (i % 3 == 1)
		{
			g[n] = dataArray[i];
			while (g[n] != item[k])
			{
				k++;
			}
			countG[k]++;
			k = 0;
			n++;
		}
		else
		{
			r[p] = dataArray[i];
			while (r[p] != item[k])
			{
				k++;
			}
			countR[k]++;
			k = 0;
			p++;
		}
	}

	//计算三通道数值的出现概率
	for (int i = 0; i < 256; i++)
	{
		countR[i] = countR[i] / (256 * 256);
		countG[i] = countG[i] / (256 * 256);
		countB[i] = countB[i] / (256 * 256);
	}
	for (int i = 0; i < 256; i++)
	{
		//cout << countR[i] << " ";
		//cout << countG[i] << " ";
		//cout << countB[i] << " ";
	}
	cout << endl;



	//定义并利用公式求信源熵
	double rEntropy = 0;
	double gEntropy = 0;
	double bEntropy = 0;

	for (int i = 0; i < 256; i++)
	{
		if (countR[i] != 0)
		{
			rEntropy = rEntropy + countR[i] * (log(1 / countR[i]) / log(2));
		}
		if (countG[i] != 0)
		{
			gEntropy = gEntropy + countG[i] * (log(1 / countG[i]) / log(2));
		}
		if (countB[i] != 0)
		{
			bEntropy = bEntropy + countB[i] * (log(1 / countB[i]) / log(2));
		}
	}

	cout << "R的熵为 " << rEntropy << "\n";
	cout << "G的熵为 " << gEntropy << "\n";
	cout << "B的熵为 " << bEntropy << "\n";

	return 0;
}

在这里插入图片描述

2.YUV代码

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <cmath>

using namespace std;

int main()
{

	int w = 256;
	int h = 256;
	int fileLength = w * h * 1.5;

	//打开、创建所需文件
	FILE* file = fopen("down.yuv", "rb");

	//动态分配地址
	unsigned char* dataArray = (unsigned char*)malloc(sizeof(unsigned char) * fileLength);
	unsigned char* v = (unsigned char*)malloc(w * h / 4 * sizeof(unsigned char));
	unsigned char* u = (unsigned char*)malloc(w * h / 4 * sizeof(unsigned char));
	unsigned char* y = (unsigned char*)malloc(w * h * sizeof(unsigned char));

	//读取文件
	fread(dataArray, sizeof(unsigned char), fileLength, file);

	//定义不同颜色通道计数
	int k = 0;
	int m = 0;  //b
	int n = 0;  //g
	int p = 0;  //r

	//定义参照数组跟三通道计数数组
	unsigned char item[256];
	double countV[256];
	double countU[256];
	double countY[256];
	for (int i = 0; i < 256; i++)
	{
		item[i] = (unsigned char)i;
		countV[i] = 0;
		countU[i] = 0;
		countY[i] = 0;
	}

	//分离RGB通道并对各通道的灰度值出现次数计数
	for (int i = 0; i < w * h; i++)
	{
		y[m] = dataArray[i];
		while (y[m] != item[k])
		{
			k++;
		}
		countY[k]++;
		k = 0;
		m++;
	}
	for (int i = w * h; i < w * h * 1.25; i++)
	{
		u[n] = dataArray[i];
		while (u[n] != item[k])
		{
			k++;
		}
		countU[k]++;
		k = 0;
		n++;
	}
	for (int i = w * h * 1.25; i < w * h * 1.5; i++)
	{
		v[p] = dataArray[i];
		while (v[p] != item[k])
		{
			k++;
		}
		countV[k]++;
		k = 0;
		p++;
	}

	//计算三通道数值的出现概率
	for (int i = 0; i < 256; i++)
	{
		countV[i] = countV[i] / (256 * 256 / 4);
		countU[i] = countU[i] / (256 * 256 / 4);
		countY[i] = countY[i] / (256 * 256);
	}
	for (int i = 0; i < 256; i++)
	{
		//cout << countY[i] << " ";
		//cout << countU[i] << " ";
		//cout << countV[i] << " ";
	}
	cout << endl;
	//定义并利用公式求信源熵
	double yEntropy = 0;
	double uEntropy = 0;
	double vEntropy = 0;

	for (int i = 0; i < 256; i++)
	{
		if (countV[i] != 0)
		{
			vEntropy = vEntropy + countV[i] * (log(1 / countV[i]) / log(2));
		}
		if (countU[i] != 0)
		{
			uEntropy = uEntropy + countU[i] * (log(1 / countU[i]) / log(2));
		}
		if (countY[i] != 0)
		{
			yEntropy = yEntropy + countY[i] * (log(1 / countY[i]) / log(2));
		}
	}

	cout << "Y的熵为 " << yEntropy << "\n";
	cout << "U的熵为 " << uEntropy << "\n";
	cout << "V的熵为 " << vEntropy << "\n";

	return 0;
}

在这里插入图片描述
四、实验分析

将cpp代码中的数据分别导入到matlab中,绘制概率分布曲线。
在这里插入图片描述
在这里插入图片描述

同理可得YUV概率分布图:
在这里插入图片描述
由上可得,rgb文件概率分布曲线与yuv文件的概率分布曲线相比,分布更加均匀。当概率分布较为均匀时,熵最大。在这里插入图片描述
因而rgb文件熵比yuv文件的熵更大,同时符合编程得出的结果。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值