0. 背景
主要是对比两张YUV图片中亮度分量Y的PSNR;
PSNR通常用于质量评价,就是计算受损图像与原始图像之间的差别,以此来评价受损图像的质量。
mse的计算公式如下:
PSNR计算公式如下:
其中M,N分别为图像的宽高,xij和yij分别为两张图像的每一个像素值。
1. 代码分析
原图与对比图,差异如下:
以下为visual studio 2019可以跑通的代码:
extern "C"
{
#ifdef __cplusplus
#define __STDC_CONSTANT_MACROS
#endif
}
extern "C" {
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
}
/**
* 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;
}
运行结果为 26.693
感谢阅读,参考链接如下:
- https://blog.youkuaiyun.com/leixiaohua1020/article/details/50534150
- https://jingyan.baidu.com/article/a17d52854451b7c198c8f2cb.html