对rgb和yuv分析三个通道的概率分布,并计算各自的熵

本文通过编程实现对RGB和YUV图像的颜色通道进行概率分布分析,并计算各自熵值。针对不同图像格式的特点,采用特定的方法处理图像数据,最终得到各通道熵值并进行比较。

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

一、实验目的
对rgb和yuv分析三个通道的概率分布,并计算各自的熵。(编程实现)

二、注意事项
①两个文件的分辨率均为256*256,
②yuv为4:2:0采样空间
③存储格式为:rgb文件按每个像素BGR分量依次存放;YUV格式按照全部像素的Y数据块、U数据块和V数据块依次存放。

三、实现过程及结果

1、rgb图像分析

源程序:

#include<stdio.h>
#include<iostream>
#include<math.h>

using namespace std;

#define A  65536 //分辨率为256*256

int main()
{
	//打开文件,创建输出文件
	FILE* image, * red, * green, * blue;
	fopen_s(&image, "C:\\Users\\LENOVO\\source\\repos\\sjyslab1\\down.rgb", "rb");
	fopen_s(&red, "C:\\Users\\LENOVO\\source\\repos\\sjyslab1\\R.txt", "w");
	fopen_s(&green, "C:\\Users\\LENOVO\\source\\repos\\sjyslab1\\G.txt", "w");
	fopen_s(&blue, "C:\\Users\\LENOVO\\source\\repos\\sjyslab1\\B.txt", "w");

	//定义R、G、B分量
	unsigned char R[A] = { 0 }, G[A] = { 0 }, B[A] = { 0 };

	//定义频率分量
	double R_F[256] = { 0 }, G_F[256] = { 0 }, B_F[256] = { 0 };

	//定义熵
	double R_S = 0, G_S = 0, B_S = 0;

	//读取R、G、B三个分量
	unsigned char sum[256 * 256 * 3];
	fread(sum, 1, 256 * 256 * 3, image);

	for (int i = 0, j = 0; i < 256 * 256 * 3; i = i + 3, j++)
	{
		B[j] = *(sum + i);
		G[j] = *(sum + i + 1);
		R[j] = *(sum + i + 2);
	}
	//计数三通道各颜色值次数
	for (int i = 0; i < 256; i++)
	{
		for (int j = 0; j < A; j++)
		{
			if (int(R[j] == i)) { R_F[i]++; }
			if (int(G[j] == i)) { G_F[i]++; }
			if (int(B[j] == i)) { B_F[i]++; }
		}
	}
	//计算频率
	for (int i = 0; i < 256; i++)
	{
		R_F[i] = R_F[i] / (256 * 256);
		B_F[i] = B_F[i] / (256 * 256);
		G_F[i] = G_F[i] / (256 * 256);
	}
	//将频率写入文件
	fprintf(red, "值\t概率\n");
	for (int i = 0; i < 256; i++)
	{
		fprintf(red, "%d\t%f\n", i, R_F[i]);
	}
	fprintf(green, "值\t概率\n");
	for (int i = 0; i < 256; i++)
	{
		fprintf(green, "%d\t%f\n", i, G_F[i]);
	}
	fprintf(blue, "值\t概率\n");
	for (int i = 0; i < 256; i++)
	{
		fprintf(blue, "%d\t%f\n", i, B_F[i]);
	}
	//计算并输出熵
	for (int i = 0; i < 256; i++)
	{
		if (R_F[i] != 0) { R_S += -R_F[i] * log(R_F[i]) / log(2); }
		if (G_F[i] != 0) { G_S += -G_F[i] * log(G_F[i]) / log(2); }
		if (B_F[i] != 0) { B_S += -B_F[i] * log(B_F[i]) / log(2); }
	}
	cout << "R的熵为" << R_S << endl;
	cout << "G的熵为" << G_S << endl;
	cout << "B的熵为" << B_S << endl;

	fclose(image);
	fclose(red);
	fclose(green);
	fclose(blue);
	return 0;
}

运行结果:
在这里插入图片描述
输出的概率分布txt文件导入Excel后并制作成折线图:
在这里插入图片描述在这里插入图片描述
2、yuv图像分析

源程序:

#include<stdio.h>
#include<iostream>
#include<math.h>

using namespace std;
#define A  65536 //分辨率为256*256

int main()
{
	//打开文件,创建输出文件
	FILE* image, * fY, * fU, * fV;
	fopen_s(&image, "C:\\Users\\LENOVO\\source\\repos\\sjyslab1\\down.yuv", "rb");
	fopen_s(&fY, "C:\\Users\\LENOVO\\source\\repos\\sjyslab1\\Y.txt", "w");
	fopen_s(&fU, "C:\\Users\\LENOVO\\source\\repos\\sjyslab1\\U.txt", "w");
	fopen_s(&fV, "C:\\Users\\LENOVO\\source\\repos\\sjyslab1\\V.txt", "w");

	unsigned char Y[A] = { 0 }, U[A / 4] = { 0 }, V[A / 4] = { 0 };
	//定义yuv分量

	double Y_F[256] = { 0 }, U_F[256] = { 0 }, V_F[256] = { 0 };
	//定义频率分量

	double Y_S = 0, U_S = 0, V_S = 0;
	//定义熵

	//分别读取YUV三个分量到数组中
	unsigned char Array[98304];
	fread(Array, 1, A * 1.5, image);
	for (int i = 0; i < A; i++)
	{
		Y[i] = *(Array + i);
	}

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

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

	//计数三通道各颜色值次数
	for (int i = 0; i < A; i++)
	{
		Y_F[Y[i]]++;
	}
	for (int i = 0; i < (A / 4); i++)
	{
		U_F[U[i]]++;
	}
	for (int i = 0; i < (A / 4); i++)
	{
		V_F[V[i]]++;
	}

	//计算频率
	for (int i = 0; i < 256; i++)
	{
		Y_F[i] = Y_F[i] / (A);
		V_F[i] = V_F[i] / (A / 4);
		U_F[i] = U_F[i] / (A / 4);
	}
	//将频率写入文件
	fprintf(fY, "值\t概率\n");
	for (int i = 0; i < 256; i++)
	{
		fprintf(fY, "%d\t%f\n", i, Y_F[i]);
	}
	fprintf(fU, "值\t概率\n");
	for (int i = 0; i < 256; i++)
	{
		fprintf(fU, "%d\t%f\n", i, U_F[i]);
	}
	fprintf(fV, "值\t概率\n");
	for (int i = 0; i < 256; i++)
	{
		fprintf(fV, "%d\t%f\n", i, V_F[i]);
	}
	//计算并输出熵
	for (int i = 0; i < 256; i++)
	{
		if (Y_F[i] != 0) { Y_S += -Y_F[i] * log(Y_F[i]) / log(2); }
		if (U_F[i] != 0) { U_S += -U_F[i] * log(U_F[i]) / log(2); }
		if (V_F[i] != 0) { V_S += -V_F[i] * log(V_F[i]) / log(2); }
	}
	cout << "Y的熵为" << Y_S << endl;
	cout << "U的熵为" << U_S << endl;
	cout << "V的熵为" << V_S << endl;

	fclose(image);
	fclose(fY);
	fclose(fU);
	fclose(fV);
	return 0;
}

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

输出的概率分布txt文件导入Excel后并制作成折线图:
在这里插入图片描述
在这里插入图片描述

在C++中,将二进制文件转换为YUV格式可以使用以下代码: ```cpp #include <iostream> #include <fstream> int main() { // 打开二进制文件 std::ifstream file("input.bin", std::ios::binary); // 读取二进制数据 file.seekg(0, std::ios::end); int fileSize = file.tellg(); file.seekg(0, std::ios::beg); char* buffer = new char\[fileSize\]; file.read(buffer, fileSize); // 将二进制数据写入YUV文件 std::ofstream yuvFile("output.yuv", std::ios::binary); yuvFile.write(buffer, fileSize); // 关闭文件 file.close(); yuvFile.close(); // 释放内存 delete\[\] buffer; return 0; } ``` 这段代码首先打开一个二进制文件,然后读取文件的内容将其写入一个YUV文件中。你可以将`input.bin`替换为你的二进制文件的路径,将`output.yuv`替换为你想要保存YUV文件的路径。请注意,这只是一个简单的示例,你可能需要根据你的具体需求进行修改。 \[1\]提供了一个示例代码,展示了如何以二进制方式读取YUV文件。 \[3\]提供了一个关于打开读写YUV文件时的注意事项。 #### 引用[.reference_title] - *1* *2* [分析RGBYUV二进制格式图像的三通道概率分布及其](https://blog.youkuaiyun.com/qq_43850979/article/details/114481511)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [对彩色YUV视频进行二进制文件读写时候的注意事项](https://blog.youkuaiyun.com/andyfu57/article/details/48004833)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值