PSNR簡介
PSNR的全稱為“Peak Signal-to-Noise Ratio”,直譯為中文就是峰值信噪比。是一種衡量圖像質量的指標。在很多領域都會需要這個指標,比如在超分辨率重建圖像的時候,PSNR就是很重要的指標了。
WIKI解釋
峰值信噪比(英語:Peak signal-to-noise ratio,常縮寫為PSNR)是一個表示信號最大可能功率和影響它的表示精度的破壞性噪聲功率的比值的工程術語。由於許多信號都有非常寬的動態范圍,峰值信噪比常用對數分貝單位來表示。
計算PSNR要先知道MSE(均方誤差)的計算。兩個m×n單色圖像I和K,如果一個為另外一個的噪聲近似,那么它們的的均方誤差定義為:
MSE的概念應該是比較熟悉的,這也是常見的損失函數。而PSNR就是通過MSE得出來的,公式如下:
其中,MAXI是表示圖像點顏色的最大數值,如果每個采樣點用 8 位表示,那么就是 255。
所以MSE越小,則PSNR越大;所以PSNR越大,代表着圖像質量越好。一般來說,
PSNR高於40dB說明圖像質量極好(即非常接近原始圖像),
在30—40dB通常表示圖像質量是好的(即失真可以察覺但可以接受),
在20—30dB說明圖像質量差;
最后,PSNR低於20dB圖像不可接受
python代碼實現PSNR計算
# PSNR.py
import numpy
import math
def psnr(img1, img2):
mse = numpy.mean( (img1 - img2) ** 2 )
if mse == 0:
return 100
PIXEL_MAX = 255.0
return 20 * math.log10(PIXEL_MAX / math.sqrt(mse))
以上代碼僅作參考之用,tensorflow框架里有直接關於psnr計算的函數,直接調用就行了:(更推薦)
注意:計算PSNR的時候必須滿足兩張圖像的size要完全一樣!
import tensorflow as tf
def read_img(path):
return tf.image.decode_image(tf.read_file(path))
def psnr(tf_img1, tf_img2):
return tf.image.psnr(tf_img1, tf_img2, max_val=255)
def _main():
t1 = read_img('t1.jpg')
t2 = read_img('t2.jpg')
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
y = sess.run(psnr(t1, t2))
print(y)
if __name__ == '__main__':
_main()
SSIM簡介
SSIM是一種衡量兩幅圖片相似度的指標。
出處來自於2004年的一篇TIP,標題為:Image Quality Assessment: From Error Visibility to Structural Similarity 論文地址,與PSNR一樣,SSIM也經常用作圖像質量的評價。
先了解SSIM的輸入
SSIM的輸入就是兩張圖像,我們要得到其相似性的兩張圖像。其中一張是未經壓縮的無失真圖像(即ground truth),另一張就是你恢復出的圖像。所以,SSIM可以作為super-resolution質量的指標。假設我們輸入的兩張圖像分別是x和y,那么
α>0, β>0β>0,and γ>0γ>0. 式1是SSIM的數學定義,其中:
其中l(x, y)是亮度比較,c(x,y)是對比度比較,s(x,y)是結構比較。μ**xμx和μ**yμy分別代表x,y的平均值,σ**xσx和σ**yσy分別代表x,y的標准差。σxyσxy代表x和y的協方差。而c1c1,c2c2,c3c3分別為常數,避免分母為0帶來的系統錯誤。
在實際工程計算中,我們一般設定α=β=γ=1α=β=γ=1,以及c3=c2/2c3=c2/2,可以將SSIM簡化為下:
總結:
- SSIM具有對稱性,即SSIM(x,y)=SSIM(y,x)
- SSIM是一個0到1之間的數,越大表示輸出圖像和無失真圖像的差距越小,即圖像質量越好。當兩幅圖像一模一樣時,SSIM=1;
如PSNR一樣,SSIM這種常用計算函數也被tensorflow收編了,我們只需在tf中調用ssim就可以了tf.image.ssim(x, y, 255)
源代碼如下:
import numpy as np
def ssim(y_true , y_pred):
u_true = np.mean(y_true)
u_pred = np.mean(y_pred)
var_true = np.var(y_true)
var_pred = np.var(y_pred)
std_true = np.sqrt(var_true)
std_pred = np.sqrt(var_pred)
c1 = np.square(0.01*7)
c2 = np.square(0.03*7)
ssim = (2 * u_true * u_pred + c1) * (2 * std_pred * std_true + c2)
denom = (u_true ** 2 + u_pred ** 2 + c1) * (var_pred + var_true + c2)
return ssim / denom