数据压缩作业1-2|针对down.rgb和down.yuv分析三个通道的概率分布,并计算各自的熵

实验任务

对文件down.rgb和down.yuv分析三个通道的概率分布,并计算各自的熵。(编程实现)两个文件的分辨率均为256*256,yuv为4:2:0采样空间,存储格式为:rgb文件按每个像素BGR分量依次存放;YUV格式按照全部像素的Y数据块、U数据块和V数据块依次存放。

实验目的

了解RGB和YUV与图像信号的联系,并能够编写程序计算各分量的熵,同时得出图像数据压缩中对RGB和YUV的分析意义。

实验内容

1.首先了解一下rgb,yuv
下面链接简单了解一下RGB与像素的关系
http://www.360doc.com/content/18/0410/09/7551_744364416.shtml
下面链接是关于YUV的介绍
https://blog.csdn.net/shayashi/article/details/82414687
2.编写程序(本人不是很会编写程序所以主要是拿现成的程序进行更改和整合)
下面是RGB分量的熵的计算

#include"iostream"
#include"math.h"
#include"windows.h"
#include"stdio.h"
using namespace std;
#define A 256*256

double shang(double freq[256])//编写一个计算熵的函数
{
	double shang = 0;
	for (int i = 0; i < 256; i++)
	{
		if (freq[i] == 0)
			continue;
		shang  = shang - freq[i] * log(freq[i]) / log(2);
	}
	return shang;
}

int main()
{
	FILE* Picture, *Red, *Green, *Blue;
	fopen_s(&Picture, "E:/大三下课程/数据压缩/down.rgb", "rb");
	fopen_s(&Red, "E:/大三下课程/数据压缩/Red.txt", "w");
	fopen_s(&Green, "E:/大三下课程/数据压缩/Green.txt", "w");
	fopen_s(&Blue, "E:/大三下课程/数据压缩/Blue.txt", "w");

	unsigned char R[A] = { 0 };
	unsigned char G[A] = { 0 };
	unsigned char B[A] = { 0 };   
	double R1[256] = { 0 }, G1[256] = { 0 }, B1[256] = { 0 };   //定义R、G、B概率分量

	if (Picture == 0)
		cout<<"无法读取图像!"<<endl;
	else
	{
		//分别读取R、G、B到数组中
		unsigned char Arr[A * 3] = { 0 };
		fread(Arr, 1, A * 3, Picture);
		for (int i = 0, j = 0; i < A * 3; i = i + 3, j++)
		{
			R[j] = *(Arr + i + 2);
			G[j] = *(Arr + i + 1);
			B[j] = *(Arr + i);
		}

		//统计频数
		for (int i = 0; i < A; i++)
		{
			R1[R[i]]++;
			G1[G[i]]++;
			B1[B[i]]++;
		}

		//计算rgb概率
		for (int i = 0; i < 256; i++)
		{
			R1[i] = R1[i] / (A);
			B1[i] = B1[i] / (A);
			G1[i] = G1[i] / (A);
		}

		//计算并输出熵
		double shangB = 0, shangG = 0, shangR = 0;
		shangR = shang(R1);
		shangG = shang(G1);
		shangB = shang(B1);
		cout << "R的熵为:" << shangR << endl;
		cout << "G的熵为:" << shangG << endl;
		cout << "B的熵为:" << shangB << endl;

		//将概率写入记事本
		for (int i = 0; i < 256; i++)
		{
			fprintf(Red, "%d\t%f\n", i, R1[i]);
			fprintf(Green, "%d\t%f\n", i, G1[i]);
			fprintf(Blue, "%d\t%f\n", i, B1[i]);
		}
	}
	system("pause");
	return 0;
}


运行结果
在这里插入图片描述

下面是对YUV部分的熵的计算

#include"iostream"
#include"Windows.h"
#include"math.h"
using namespace std;

#define A 256*256

double shang(double freq[256])//编写一个计算熵的函数
{
	double shang = 0;
	for (int i = 0; i < 256; i++)
	{
		if (freq[i] == 0)
			continue;
		shang = shang - freq[i] * log(freq[i]) / log(2);
	}
	return shang;
}

int main()
{
	

	FILE* Picture, *PalY, *PalU, *PalV;
	fopen_s(&Picture, "E:/大三下课程/数据压缩/down.yuv", "rb");
	fopen_s(&PalY, "E:/大三下课程/数据压缩/PalY.txt", "w");
	fopen_s(&PalU, "E:/大三下课程/数据压缩/PalU.txt", "w");
	fopen_s(&PalV, "E:/大三下课程/数据压缩/PalV.txt", "w");

	unsigned char Y[A] = { 0 };
	unsigned char U[A / 4] = { 0 };
	unsigned char V[A / 4] = { 0 };    //定义Y、U、V分量,其中4:2:0格式中,width * hight =Y(总和) U = Y / 4   V = Y / 4
	double Y1[256] = { 0 }, U1[256] = { 0 }, V1[256] = { 0 };   //定义Y、U、V概率分量


	if (Picture == 0)
		printf("无法读取图像");
	else
	{
		//分别读取Y、U、V到数组中
		unsigned char Arr[98304];
		fread(Arr, 1, A * 1.5, Picture);
		for (int i = 0; i < A; i++)
		{
			Y[i] = *(Arr + i);
		}

		for (int i = A; i < A * 1.25; i++)
		{
			U[i - 65536] = *(Arr + i);
		}

		for (int i = A * 1.25; i < A * 1.5; i++)
		{
			V[i - 81920] = *(Arr + i);
		}

		//统计频数
		for (int i = 0; i < A; i++)
		{
			Y1[Y[i]]++;
		}

		for (int i = 0; i < (A / 4); i++)
		{
			U1[U[i]]++;
			V1[V[i]]++;
		}

		//计算yuv概率
		for (int i = 0; i < 256; i++)
		{
			Y1[i] = Y1[i] / (A);
			U1[i] = U1[i] / (A / 4);
			V1[i] = V1[i] / (A / 4);
		}

		//计算并输出熵
		double Y2 = 0, U2 = 0, V2 = 0;
		Y2 = shang(Y1);
		U2 = shang(U1);
		V2 = shang(V1);
		cout << "Y的熵为:" << Y2 << endl;
		cout << "U的熵为:" << U2 << endl;
		cout << "V的熵为:" << V2 << endl;

		//将概率写入记事本
		for (int i = 0; i < 256; i++)
		{
			fprintf(PalY, "%d\t%f\n", i, Y1[i]);
			fprintf(PalU, "%d\t%f\n", i, U1[i]);
			fprintf(PalV, "%d\t%f\n", i, V1[i]);
		}
	}
	system("pause");
	return 0;
}

运行结果如下
在这里插入图片描述

3.绘制概率分布图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
4.部分数据内容
下面是部分的数据内容,用程序是写入记事本的,为方便观看和作图,导入Excel中
在这里插入图片描述

实验结果分析

  • 从程序运行结果可以看出RGB分量的熵较YUV分量的熵要大一些;
  • 从折线图的分布可以看出RGB概率分布相对分散,而YUV的较为集中;
  • 对于数据压缩来说,所谓"压缩"就是找出文件内容的概率分布,将那些出现概率高的部分代替成更短的形式。所以,内容越是重复的文件,就可以压缩地越小。熵越大,就意味着内容越分散,要求压缩的量也就越大,所以从这个角度来看,4:2:0的YUV格式要比RGB格式进行压缩的效果要好,压缩效率更高。

总结

  • 从老师上课的内容来看,此次实验主要是想要我们了解图像压缩途径,并计算这两种途径的熵,从熵可以得到两种压缩数据的能力,是我们更深刻的了解这门课程开设的目的。其实之前学信息论与编码的时候,对有些概念不是很理解,但是通过实际操作和计算,也能了解一点关于计算熵,研究熵的作用,单单从这个小作业就好像可以看到数据压缩的重大作用,想想,如果能够将数据压缩极致化(好像香农定理告诉我们:信道信息传送速率的上限(比特每秒)和信道信噪比及带宽的关系,这个其实我还是不是很明白,不知道有没有关系),那么信息传输将更为高效方便,在这个什么都讲究高效快捷的世界,数据压缩还是很重要的。
  • 还有一点就是,真的要好好学编程,不然在理工科专业真是寸步难行,而且缺乏创造性的东西,就像没有自己的东西一样。所以还是要努力学习!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值