一、概述
PSNR(Peak signal-to-noise ratio)峰值信噪比,是一个表示信号最大可能功率和影响它的表示精度的破坏性噪声功率的比值的工程术语。由于许多信号都有非常宽的动态范围,峰值信噪比常用对数分贝单位来表示。它的计算公式定义如下:
MSE为两个m×n单色图像I和K(I为一无噪声的原始图像,K为I的噪声近似。例如:I为未压缩的原始图像,K为I经过压缩后的图像)残差值的平方。计算公式如下:
需要注意这里特别强调是单色图像,若文件是RGB24格式,计算出来的PSNR就有PSNR_R/PSNR_G/PSNR_B三个分量。若文件是YUV格式,那么计算出来的PSNR就有PSNR_Y/PSNR_U/PSNR_V三个分量。
MAXI是表示图像点颜色的最大数值,如果每个采样点用 8 位表示,那么就是255。
从上述公式中,可以看到实际当MSE无限小,接近0的时候,PSNR的值可以无限大。但是实际工具实现的时候,会进行截断。比方说webrtc会配置PSNR的最大值为128。VMAF配置是60(MAXI是255的情况下)。
二、webrtc代码实现
psnr_ssim_analyzer.cc
->main()
->CompareFiles()
->Psnr()
->libyuv::I420Psnr()
1)分别计算Y、U、V分量的SSE值。
2)SSE计算
3)计算PSNR值
可以看出webrtc是将Y、U、V三个分量的SSE值都算出来,取平均值,计算的PSNR。
但是在有些PSNR计算工具里面,例如X265代码里面,会分别计算三个分量的PSNR值。
然后计算YUV三个分量的加权平均值。获取一个总值。
1)FrameFilter::processPostRow计算SSE
2)Encoder::finishFrameStats计算三个分量的PSNR值,和PSNR的加权平均值
X265之所以这么做是因为人眼对Y亮度分量敏感,对U、V分量不那么敏感,这种加权平均值的算法,更符合人眼的主观感受。
三、PSNR值说明
虽然不同工具算出来的值,取值范围不同。但是无论什么工具,在PSNR小于50db以内,值还是基本一致的。PSNR值和视频质量的对应关系如下:
图像与影像压缩中典型的峰值信噪比值在30dB到50dB之间,愈高愈好。
PSNR接近50dB,代表压缩后的图像仅有些许非常小的误差。
PSNR大于30dB,人眼很难查觉压缩后和原始影像的差异。
PSNR介于20dB到30dB之间,人眼就可以察觉出图像的差异。
PSNR介于10dB到20dB之间,人眼还是可以用肉眼看出这个图像原始的结构,且直观上会判断两张图像不存在很大的差异。
PSNR低于10dB,人类很难用肉眼去判断两个图像是否为相同,一个图像是否为另一个图像的压缩结果。
四、参考
https://zh.wikipedia.org/wiki/%E5%B3%B0%E5%80%BC%E4%BF%A1%E5%99%AA%E6%AF%94