统计RGB和YUV图像文件各分量的概率分布并求出熵

实验目的

给定两图片down.rgbdown.yuv,分辨率为256*256,色度采样格式4:2:0,统计RGB和YUV图像文件各分类的概率分布,并求出熵

实验思路

实验用C++完成运算部分,为了方便绘图,将数据导出,进入Excel绘图(便于操作)

数据处理

RGB文件按BRGBRG…顺序循环,256*256格式应有196608个数据,YUV文件Y占65536,U、V各占16384。

代码部分

#include<iostream>
#include<fstream>
using namespace std;
#define size 65536
//处理RGB格式文件
void H_RGB(unsigned char* buffer)
{
	FILE* fp,*Red,*Green,*Blue;
	double level_r[256] = { 0 },level_g[256] = { 0 },level_b[256] = { 0 };
	double r[256] = { 0 }, g[256] = { 0 },b[256] = { 0 };
	double Hr = 0, Hg = 0, Hb = 0;
	fopen_s(&fp, "E:\\DCE\\down.rgb", "rb");
    if (fp == 0)
        return;
    //以下会创建三个txt文件,用来后续接收概率数据,与求熵无关
	fopen_s(&Red, "E:\\DCE\\Red.txt", "w");
	fopen_s(&Green, "E:\\DCE\\Green.txt", "w");
	fopen_s(&Blue, "E:\\DCE\\Blue.txt", "w");
	//以下先读取数据

	fread(buffer, size * 3, 1, fp);
	for (int i = 0; i < size * 3; i)
	{
		level_b[buffer[i++]] ++;
		level_g[buffer[i++]] ++;
		level_r[buffer[i++]] ++;
	}

    //以下为运算部分

	for (int i = 0; i < 256; i++)
	{
		r[i] = level_r[i] / (size);
		b[i] = level_b[i] / (size);
		g[i] = level_g[i] / (size);
	}

    //以下为写数据进入txt文件,与求熵无关
	for (int i = 0; i < 256; i++)
	{
		fprintf(Red, "%d\t%f\n", i, r[i]);
		fprintf(Green, "%d\t%f\n", i, g[i]);
		fprintf(Blue, "%d\t%f\n", i, b[i]);
	}
    //求熵
    for (int i = 0; i < 256; i++)
    {
        if (b[i] != 0) { Hb = Hb - (b[i]) * (log(b[i]) / (log(2.0)));}
        if (g[i] != 0) { Hg = Hg - (g[i]) * (log(g[i]) / (log(2.0)));}
        if (r[i] != 0) { Hr = Hr - (r[i]) * (log(r[i]) / (log(2.0)));}
    }
	printf("Hr=%f\n", Hr);
    printf("Hg=%f\n", Hg);
    printf("Hb=%f\n", Hb);
}
//处理YUV格式文件
void H_YUV(unsigned char* buffer)
{
    unsigned char Y[size] = { 0 }, U[size / 4] = { 0 }, V[size / 4] = { 0 };
    //unsigned char buffer[98304];
    double y[256] = { 0 }, u[256] = { 0 }, v[256] = { 0 }; 
    double Hy = 0, Hu = 0, Hv = 0;


    FILE* Pic, * PY, * PU, * PV;
    fopen_s(&Pic, "E:\\DCE\\down.yuv", "rb");
    if (Pic == 0)
        return;
    //以下会创建三个txt文件,用来后续接收概率数据,与求熵无关
    fopen_s(&PY, "E:\\DCE\\PY.txt", "w");
    fopen_s(&PU, "E:\\DCE\\PU.txt", "w");
    fopen_s(&PV, "E:\\DCE\\PV.txt", "w");
    //以下先读取数据
    
    fread(buffer, 1, size * 1.5, Pic);
    for (int i = 0; i < size; i++)
    {
        Y[i] = *(buffer + i);
    }

    for (int i = 0; i < size * 0.25; i++)
    {
        U[i] = *(buffer+ 65536 + i);
    }

    for (int i = 0; i < size * 0.25; i++)
    {
        V[i] = *(buffer+ 81920 + i);
    }
    //以下为运算部分
    for (int i = 0; i < size; i++)
    {
        y[Y[i]]++;
    }

    for (int i = 0; i < (size / 4); i++)
    {
        u[U[i]]++;
        v[V[i]]++;
    }

    for (int i = 0; i < 256; i++)
    {
        y[i] = y[i] / (size);
        u[i] = u[i] / (size / 4);
        v[i] = v[i] / (size / 4);
    }
    //以下为写数据进入txt文件,与求熵无关
    for (int i = 0; i < 256; i++)
    {
        fprintf(PY, "%d\t%f\n", i, y[i]);
        fprintf(PU, "%d\t%f\n", i, u[i]);
        fprintf(PV, "%d\t%f\n", i, v[i]);
    }
    //求熵
    for (int i = 0; i < 256; i++)
    {
        if (y[i] != 0) { Hy += -y[i] * log(y[i]) / log(2.0); }
        if (u[i] != 0) { Hu += -u[i] * log(u[i]) / log(2.0); }
        if (v[i] != 0) { Hv += -v[i] * log(v[i]) / log(2.0); }
    }
    printf("Hy=%f\n", Hy);
    printf("Hu=%f\n", Hu);
    printf("Hv=%f\n", Hv);
}
//主函数
int main()
{

	unsigned char* RGB_buffer;
	unsigned char* YUV_buffer;

	RGB_buffer = new unsigned char[size * 3];
	YUV_buffer = new unsigned char[size * 1.5];
	H_RGB(RGB_buffer);
    H_YUV(YUV_buffer);
	return 0;
}

得到结果

在这里插入图片描述在这里插入图片描述

所得熵

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值