读取分析RGB文件

作业3:读入一个24bitRGB文件(以down.rgb为例,其分辨率为256*256),输出该数据文件中R、G、B三个分量(各8bit表示)的概率分布示意图(类似下图)和熵。

提示:(用C或C++实现时),程序的流程为:

开辟3个width*height的unsigned char型数组;打开要读出的RGB文件(以“rb”方式打开),打开3个要输出的数据统计文件(以“w”方式打开,可命名为R_sat.txt等);将RGB数据从RGB文件中读出,并分别保存到3个数组中,期间计算数据的概率分布和熵,并将这些数据写入3个数据统计txt文件中。Txt文件的写入方式如下所示(每行的两个数据用tab分开)。在Excel里将这3个txt文件打开即可生成统计图。

代码如下:

#include "pch.h"
#include <iostream>

int main()
{
	constexpr auto width = 256;
    constexpr auto height = 256;
	errno_t err;

	FILE* fp; //设置一文件指针
	FILE *fr, *fg, *fb;
	if ((err = fopen_s(&fp, "down.rgb", "rb")) == 0)//打开rgb文件
		printf("The file 'down.rgb' was opened\n");
	else
		printf("The file 'down.rgb' was not opened\n");

	if ((err = fopen_s(&fr, "R_sat.txt", "w")) == 0)//打开三个要输入数据的统计文件
		printf("The file 'R_sat.txt' was opened\n");
	else
		printf("The file 'R_sat.txt' was not opened\n");

	if ((err = fopen_s(&fg, "G_sat.txt", "w")) == 0)
		printf("The file 'G_sat.txt' was opened\n");
	else
		printf("The file 'G_sat.txt' was not opened\n");

	if ((err = fopen_s(&fb, "B_sat.txt", "w")) == 0)
		printf("The file 'B_sat.txt' was opened\n");
	else
		printf("The file 'B_sat.txt' was not opened\n");

	unsigned char *buffer;//设置动态内存地址
	buffer = (unsigned char*)malloc(sizeof(unsigned char)*width*height * 3);//分配动态内存
	if (buffer == NULL)
	{
		printf("申请失败");
	}

	fread(buffer, sizeof(unsigned char), width*height*3, fp);//将rgb文件中的数据读至buffer指向的动态空间

	unsigned char B[width*height] = { 0 };
	unsigned char G[width*height] = { 0 };
	unsigned char R[width*height] = { 0 };
	int i;
	int j;

	/*for (i = 0; i < width*height; i++)
	{
		R[i] = *(buffer + 3*i) && 0x000000FF;
		G[i] = *(buffer + 3*i) && 0x0000FF00;
		B[i] = *(buffer + 3*i) && 0x00FF0000;
	}*///用单片机的方法写崩了-__-||

	for (i = 0; i < width*height; i++)
	{
		B[i] = *(buffer + 3 * i);
		G[i] = *(buffer + 3 * i+1);
		R[i] = *(buffer + 3 * i+2);	
	}

	int numR[256] = { 0 };
	double freqR[256] = { 0 };
	for (i = 0; i < 256; i++)
	{
		for (j = 0; j < width*height; j++)
		{
			if (R[j] == i)
			{
				numR[i]++;
			}
		}
		freqR[i] =double(numR[i]) / (width * height);
	}
	//printf("%f", freqR[1]);
	int numG[256] = { 0 };
	double freqG[256] = { 0 };
	for (i = 0; i < 256; i++)
	{
		for (j = 0; j < width*height; j++)
		{
			if (G[j] == i)
			{
				numG[i]++;
			}
		}
		freqG[i] = double(numG[i]) / (width * height);
	}

	int numB[256] = { 0 };
	double freqB[256] = { 0 };
	for (i = 0; i < 256; i++)
	{
		for (j = 0; j < width*height; j++)
		{
			if (B[j] == i)
			{
				numB[i]++;
			}
		}
		freqB[i] =double(numB[i]) / (width * height);
	}
	
	//计算熵
	double HR=0;
	for (i = 0; i < 256; i++)
	{
		if (freqR[i] != 0)
		{
			HR = HR - freqR[i] *log(freqR[i]) / log(2);
		}
	}
	double HG=0;
	for (i = 0; i < 256; i++)
	{
		if (freqG[i] != 0)
		{
			HG = HG - freqG[i] * log(freqG[i]) / log(2);
		}
	}
	double HB=0;
	for (i = 0; i < 256; i++)
	{
		if (freqB[i] != 0)
		{
			HB = HB - freqB[i] * log(freqB[i]) / log(2);
		}
	}

	printf("R的熵为:%f\n", HR);
	printf("G的熵为:%f\n", HG);
	printf("B的熵为:%f\n", HB);


	fprintf(fr, "%s\t%s\n", "symbol", "frequent");
	for (i = 0; i < 256; i++)
	{
		fprintf(fr, "%d\t%f\n", i, freqR[i]);
	}
	
	fprintf(fg, "%s\t%s\n", "symbol", "frequent");
	for (i = 0; i < 256; i++)
	{
		fprintf(fg, "%d\t%f\n", i, freqG[i]);
	}

	fprintf(fb, "%s\t%s\n", "symbol", "frequent");
	for (i = 0; i < 256; i++)
	{
		fprintf(fb, "%d\t%f\n", i, freqB[i]);
	}

	free(buffer);
	fclose(fp);
	fclose(fr);
	fclose(fg);
	fclose(fb);

	system("pause");
	return 0;


}

结果:
R分量概率分布
R分量

G分量概率分布G分量

B分量概率分布B分量

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值