视频质量评价PSNR

        PSNR(Peak Signal to Noise Ratio,峰值信噪比)是最基础的视频质量评价方法。它的取值一般在20-50之间,值越大代表受损图片越接近原图片。PSNR通过对原始图像和失真图像进行像素的逐点对比,计算两幅图像像素点之间的误差,并由这些误差最终确定失真图像的质量评分。该方法由于计算简便、数学意义明确,在图像处理领域中应用最为广泛。

一幅MxN尺寸的图像的PSNR的计算公式如下所示:

视频质量评价PSNR_第1张图片

其中xij 和yij 分别表示失真图像和原始图像对应像素点的灰度值;

i,j 分别代表图像的行和列;

L 是图像灰度值可到达的动态范围,8位的灰度图像的L=2^8-1=255。

如果已知SSD,MxN尺寸图像的PSNR公式如下所示。

MSE=SSD*1/(M*N)

PSNR=10*lg(255^2/MSE)

    例如下图两张1080图片(左边是原图,右边是编码之后的图片,QP为17)的PSNR对比的结果 Y PSNR is 40.632022, U PSNR is 44.596545,V PSNR is 45.759277

视频质量评价PSNR_第2张图片

PSNR对比测试:
1080P视频测试:BasketballDrive_1920x1080_25_250.yuv
dp:17
 Y PSNR is 40.632022, U PSNR is 44.596545,V PSNR is 45.759277
dp:28
 Y PSNR is 38.834869, U PSNR is 42.445172,V PSNR is 42.977148
dp:32
 Y PSNR is 38.144906, U PSNR is 41.265455,V PSNR is 41.705576
dp:36
 Y PSNR is 37.527187, U PSNR is 40.110563,V PSNR is 40.551498
        我们知道量化和反量化过程中,量化步长QP决定量化器的编码压缩率及图像精度。如果QP比较大,则量化值FQ动态范围越小,其相应的编码长度越小,但反量化是损失较多的图像细节,导致PSNR值越小。

代码:

// PSNR_CAL.cpp : 定义控制台应用程序的入口点。
//PSNR (Peak Signal to Noise Ratio)
//峰值信噪比PSNR衡量图像失真或是噪声水平的客观标准。2个图像之间PSNR值越大,则越相似。普遍基准为30dB,30dB以下的图像劣化较为明显。
#include "stdafx.h"
#include 
#include 
#include 
#include 

#define VIDEO_WIDTH			1280
#define VIDEO_HEIGHT		720
#define VIDEO_FRAME_NUM			10 //frame number
//编码解码YUV
#define DEC_YUV_PATH			"E:\\yuv\\\\bs3.yuv"
//原YUV
#define REF_YUV_PATH			"E:\\yuv\\BasketballDrive_1920x1080_25_250.yuv"
#define REF_YUV_422			0 //1:reference yuv is 422 format, 0:reference yuv is 420 format
#define VIDEO_SIZE_Y		VIDEO_HEIGHT*VIDEO_WIDTH
#define VIDEO_SIZE_UV		(VIDEO_HEIGHT*VIDEO_WIDTH)>>1
#define VIDEO_SIZE_YUV		(VIDEO_SIZE_Y + VIDEO_SIZE_UV)
#define CONV422	0
#define CAL_PSNR 1

int main()
{
	FILE *fp_dec;
	FILE *fp_ref;
	int i, j, k, comp;

#if CAL_PSNR
	unsigned char line_dec[5000];
	unsigned char line_ref[5000];
	int  idiff;
	unsigned long diff_sum;
	int width, height;
	double psnr_frame;
	double psnr_sum[VIDEO_FRAME_NUM][3];
	double psnr_total[3];
	
	fp_dec = fopen(DEC_YUV_PATH, "rb");
	fp_ref = fopen(REF_YUV_PATH, "rb");
	
	if (fp_dec == NULL)
	{
		printf("\n DEC YUV file not found\n");
		return 0;
	}

	if (fp_ref == NULL)
	{
		printf("\n REF YUV file not found\n");
		return 0;
	}

	for (i = 0; i < VIDEO_FRAME_NUM; i++)
	{	//Y
		for (comp = 0; comp < 3; comp++)
		{
			diff_sum = 0;
			if(comp ==0)
			{
				width = VIDEO_WIDTH;
				height = VIDEO_HEIGHT;
			}
			else
			{
				width = VIDEO_WIDTH /2;
				height = VIDEO_HEIGHT /2;
			}

			for (j = 0; j < height; j++)
			{
				fread(line_dec, 1, width, fp_dec);
				fread(line_ref, 1, width, fp_ref);

				//fwrite(line_ref, 1, width, fp_ref_422);

				//if(comp != 0)							//UV
				//	fwrite(line_ref, 1, width, fp_ref_422);

				for (k = 0; k < width; k++)
				{
					idiff = (int)(line_dec[k] - line_ref[k]);
					diff_sum += idiff*idiff;

					//if (k == 0 && j == 5 )
					//	printf("stop at %d", k);
				}
				//if (comp != 0 && REF_YUV_422 == 1) // if 422 format, skip one chroma line
				//	fread(line_dec, 1, width, fp_dec);
			}
			psnr_frame = (double)255 * 255 * width* height;
			psnr_sum[i][comp] = 10.0 * log10(psnr_frame / (double)diff_sum);
		}
		printf("frame %d, Y PSNR is %f, Cb PSNR is %f,Cr PSNR is %f \n", i, psnr_sum[i][0], psnr_sum[i][1], psnr_sum[i][2]);
	}
	psnr_total[0] = 0;
	psnr_total[1] = 0;
	psnr_total[2] = 0;

	for (i = 0; i

       但是PSNR仅仅计算了图像像素点间的绝对误差,没有考虑像素点间的视觉相关性,更没顾及人类视觉系统的感知特性,所以其评价结果与主观感受往往相差较大(SSIM就是一种典型的与人类视觉系统特性结合的质量评价方法)。

你可能感兴趣的:(音视频与图像处理)