[Video and Audio Data Processing] 计算两个YUV420P像素数据的PSNR

0. 背景

主要是对比两张YUV图片中亮度分量Y的PSNR;

PSNR通常用于质量评价,就是计算受损图像与原始图像之间的差别,以此来评价受损图像的质量。

mse的计算公式如下:
在这里插入图片描述

PSNR计算公式如下:
在这里插入图片描述
其中M,N分别为图像的宽高,xij和yij分别为两张图像的每一个像素值。

1. 代码分析

原图与对比图,差异如下:
[Video and Audio Data Processing] 计算两个YUV420P像素数据的PSNR_第1张图片

以下为visual studio 2019可以跑通的代码:

extern "C"
{
#ifdef __cplusplus
#define __STDC_CONSTANT_MACROS

#endif

}
extern "C" {

#include 
#include 
#include 
#include 
}



/**
 * Calculate PSNR between 2 YUV420P file
 * @param url1     Location of first Input YUV file.
 * @param url2     Location of another Input YUV file.
 * @param w        Width of Input YUV file.
 * @param h        Height of Input YUV file.
 * @param num      Number of frames to process.
 */
int simplest_yuv420_psnr(const char* url1,const char* url2, int w, int h, int num) {
	FILE* fp1 = fopen(url1, "rb+");
	FILE* fp2 = fopen(url2, "rb+");
	unsigned char* pic1 = (unsigned char*)malloc(w * h);//分配内存空间
	unsigned char* pic2 = (unsigned char*)malloc(w * h);//分配内存空间

	for (int i = 0; i < num; i++) {
		fread(pic1, 1, w * h, fp1);//前w*h数据存储亮度分量
		fread(pic2, 1, w * h, fp2);//前w*h数据存储亮度分量

		double mse_sum = 0, mse = 0, psnr = 0;
		for (int j = 0; j < w * h; j++) {
			mse_sum += pow((double)(pic1[j] - pic2[j]), 2);//取每个差值的平方,然后总的加起来
		}
		mse = mse_sum / (w * h); //根据公式获取mse
		psnr = 10 * log10(255.0 * 255.0 / mse); //根据公式计算psnr
		printf("%5.3f\n", psnr);

		fseek(fp1, w * h / 2, SEEK_CUR);//文件指针指向文件尾
		//也可以这样写:fseek(fp1, 0 , SEEK_END);
		fseek(fp2, w * h / 2, SEEK_CUR);
		//也可以这样写:fseek(fp1, 0 , SEEK_END);

	}

	free(pic1);
	free(pic2);
	fclose(fp1);
	fclose(fp2);
	return 0;


}



int main()
{
	simplest_yuv420_psnr("lena_256x256_yuv420p.yuv", "lena_distort_256x256_yuv420p.yuv", 
	256, 256, 1);
    return 0;
}

[Video and Audio Data Processing] 计算两个YUV420P像素数据的PSNR_第2张图片

运行结果为 26.693

感谢阅读,参考链接如下:

  1. https://blog.csdn.net/leixiaohua1020/article/details/50534150
  2. https://jingyan.baidu.com/article/a17d52854451b7c198c8f2cb.html

你可能感兴趣的:(视音频数据处理)