python 计算PSNR

原文链接:https://blog.csdn.net/u010886794/article/details/84784453

一.公式计算

峰值信噪比(Peak Signal to Noise Ratio,PSNR)经常用来评价图像质量。对于一张RGB三通道图像,其计算公式如下:

先计算图像与Ground Truth的均方误差MSE:

MSE=\frac{1}{mnc}\sum_{0}^{m-1}\sum_{0}^{n-1}\sum_{0}^{c-1}= \left \| I(m,n,c)-gt(m,n,c) \right \|^{2}

再计算PSNR:

PSNR=10\cdot log10(\frac{MAX_{I}^{2}}{MSE})=20\cdot log10(\frac{MAX_{I}}{\sqrt{MSE}})

计算PSNR的Python代码,网上有下面两种:


 
 
  1. import cv2
  2. import numpy as np
  3. import math
  4. def psnr1(img1, img2):
  5. mse = np.mean((img1 - img2) ** 2 )
  6. if mse < 1.0e-10:
  7. return 100
  8. return 10 * math.log10( 255.0** 2/mse)
  9. def psnr2(img1, img2):
  10. mse = np.mean( (img1/ 255. - img2/ 255.) ** 2 )
  11. if mse < 1.0e-10:
  12. return 100
  13. PIXEL_MAX = 1
  14. return 20 * math.log10(PIXEL_MAX / math.sqrt(mse))

理论上,这两种计算方式都对应上面的计算公式,在输入图像一样的情况下,这两段代码的结果应该是一样的。但是,在调用这段代码的时候,我发现这两者的结果却相差很远,同样的图片,psnr1的结果大概是29,而psnr2的结果是12。


 
 
  1. gt = cv2.imread( '1.jpg')
  2. img= cv2.imread( '2.jpg')
  3. print(psnr1(gt,img))
  4. print(psnr2(gt,img))

这是输出的结果: 

 

单看代码的话完全看不出来任何问题,后来我输出了这两张图像作差的结果,发现所有的值都是在0-255之间的,比如img1的一个像素值是30,img2的一个像素值是60,二者作差,本来应该是-30,但是结果却是226,即对于负值,输出要加上256。所以,问题就出在这行代码上:

mse = np.mean((img1 - img2) ** 2 )
 
 

如果img1某个点的像素比img2小,而两者差别又比较大,这个绝对值比较大的负值就会变成一个比较小的正值,MSE的结果也会偏小,那么PSNR的值就会偏大。

只要把上面那行代码改成mse = np.mean((img1/1.0 - img2/1.0) ** 2 )就可以了。

最后,我们发现这两个结果是一样的了。

二.内置函数

import skimage.color as sc
import skimage
from skimage import measure

 class PSNRMetric(BaseMetric):
        def __init__(self):
            self.name = 'psnr'

        def evaluate(self, gt, pr):
            gt = self.image_preprocess(gt)
            pr = self.image_preprocess(pr)
            return skimage.measure.compare_psnr(gt, pr, data_range=255) 
            ''' 上面的函数为计算PSNR的内置方法'''
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值