python簡單代碼,【python】psnr原理簡介及代碼實現

 2023-11-14 阅读 34 评论 0

摘要:寫在前面 psnr作為圖像質量評價指標,在很多圖像領域如圖像超分辨率、圖像壓縮、圖像去噪等都有廣泛的應用。 PSNR(峰值信噪比) 簡介 Peak signal-to-noise ratio(簡稱PSNR)是一個工程術語,表示信號的最大可能功率與影響信號表示精度

寫在前面

psnr作為圖像質量評價指標,在很多圖像領域如圖像超分辨率、圖像壓縮、圖像去噪等都有廣泛的應用。

PSNR(峰值信噪比)

簡介

Peak signal-to-noise ratio(簡稱PSNR)是一個工程術語,表示信號的最大可能功率與影響信號表示精度的干擾噪聲功率之間的比值。由于許多信號都有非常寬的動態范圍,峰值訊噪比常用對數分貝單位來表示。

定義

它常簡單地通過均方誤差(MSE)進行定義。兩個 m×nm×nm×n 單色圖像 IIIKKKIII 為一無噪聲的原始圖像,KKKIII 的噪聲近似(例: III 為未壓縮的原始圖像,KKKIII 經過壓縮后的圖像),那么它們的的均方誤差定義為:
MSE=1mn∑i=0m?1∑j=0n?1[I(i,j)?K(i,j)]2{\displaystyle {\mathit {MSE}}={\frac {1}{mn}}\sum _{i=0}^{m-1}\sum _{j=0}^{n-1}[I(i,j)-K(i,j)]^{2}} MSE=mn1?i=0m?1?j=0n?1?[I(i,j)?K(i,j)]2
峰值信噪比定義為:
PSNR=10?log?10(MAXI2MSE)=20?log?10(MAXIMSE){\displaystyle {\mathit {PSNR}}=10\cdot \log _{10}\left({\frac {{\mathit {MAX}}_{I}^{2}}{\mathit {MSE}}}\right)=20\cdot \log _{10}\left({\frac {{\mathit {MAX}}_{I}}{\sqrt {\mathit {MSE}}}}\right)} PSNR=10?log10?(MSEMAXI2??)=20?log10?(MSE?MAXI??)
其中,MAXIMAX_{I}MAXI? 是表示圖像點顏色的最大數值,如果每個采樣點用 8 位表示(例:影像處理),那么就是 255。更為通用的表示是,如果每個采樣點用 B 位線性脈沖編碼調制表示,那么 MAXIMAX_{I}MAXI? 就是:
2B?1{\displaystyle 2^{B}-1} 2B?1
對于每點有RGB三個值的彩色圖像來說,峰值信噪比的定義類似。除了橫軸、縱軸 mmmnnn 以外,還要考慮它的顏色組成RGB。我們需要分別對每個顏色處理其MSE,因為有3個顏色通道,所以MSE需再除以3。

彩色圖像的峰值訊噪比定義為:
PSNR=10?log?10(MAXI213mn∑R,G,B∑i=0m?1∑j=0n?1[Icolor(i,j)?Kcolor(i,j)]2){\displaystyle {\mathit {PSNR}}=10\cdot \log _{10}\left({\frac {{\mathit {MAX}}_{I}^{2}}{{\frac {1}{3mn}}\sum _{R,G,B}^{}\sum _{i=0}^{m-1}\sum _{j=0}^{n-1}[I_{color}(i,j)-K_{color}(i,j)]^{2}}}\right)} PSNR=10?log10?(3mn1?R,G,B?i=0m?1?j=0n?1?[Icolor?(i,j)?Kcolor?(i,j)]2MAXI2??)

實現

python簡單代碼,這是我一開始寫的代碼,兩個地方有點問題,也是大家常會犯的錯誤。

from PIL import Image
import numpy as npimg1 = np.array(Image.open('original.jpg'))
img2 = np.array(Image.open('compress.jpg'))def psnr(img1, img2):mse = np.mean((img1-img2)**2)if mse == 0:return 100else:return 20*np.log10(255/np.sqrt(mse))if __name__ == "__main__":print(psnr(img1, img2))

1、如果mse == 0不應該返回100,而是正無窮,正無窮在python中用float('inf')表示。(參考維基英文百科:In the absence of noise, the two images III and KKK are identical, and thus the MSE is zero. In this case the PSNR is infinite.)

2、數據類型的問題。img1img2原本是np.int8類型,應該轉換為np.float64再參與計算,否則會導致精度丟失,計算的psnr值偏大。(這里參考了psnr百科詞條中的matlab代碼實現,代碼中對圖片進行了double操作,學過matlab的同學應該清楚,這就是將無符號int8類型轉換為雙精度浮點型

修改后的代碼:

from PIL import Image
import numpy as npimg1 = np.array(Image.open('original.jpg')).astype(np.float64)
img2 = np.array(Image.open('compress.jpg')).astype(np.float64)def psnr(img1, img2):mse = np.mean((img1-img2)**2)if mse == 0:return float('inf')else:return 20*np.log10(255/np.sqrt(mse))if __name__ == "__main__":print(psnr(img1, img2))

如果你不想自己寫,也可以調用第三方庫skimage實現,里面有封裝好的計算psnr的代碼,和我修改后的代碼計算結果是一模一樣的,具體調用方式如下:

from skimage.metrics import peak_signal_noise_ratio as psnr
from PIL import Image
import numpy as npimg1 = np.array(Image.open('original.jpg'))
img2 = np.array(Image.open('compress.jpg'))if __name__ == "__main__":print(psnr(img1, img2))

python 類,備注:skimage的大名叫scikit-image,安裝請用pip install scikit-image

意義

  • PSNR接近 50dB ,代表壓縮后的圖像僅有些許非常小的誤差。
  • PSNR大于 30dB ,人眼很難查覺壓縮后和原始影像的差異。
  • PSNR介于 20dB 到 30dB 之間,人眼就可以察覺出圖像的差異。
  • PSNR介于 10dB 到 20dB 之間,人眼還是可以用肉眼看出這個圖像原始的結構,且直觀上會判斷兩張圖像不存在很大的差異。
  • PSNR低于 10dB,人類很難用肉眼去判斷兩個圖像是否為相同,一個圖像是否為另一個圖像的壓縮結果。
同壓縮比例的PSNR比較(點擊圖片可放大)圖片為臺灣桃園國際機場停機坪
未壓縮的原圖PSNR 47.61dBPSNR 34.02dBPSNR 24.46dB

拓展閱讀

psnr的matlab實現:

function PSNR = psnr(f1, f2)
%計算兩幅圖像的峰值信噪比
k = 8;
%k為圖像是表示地個像素點所用的二進制位數,即位深。
fmax = 2.^k - 1;
a = fmax.^2;
MSE =(double(im2uint8(f1)) -double( im2uint8(f2))).^2;
b = mean(mean(MSE));
PSNR = 10*log10(a/b);

相關推薦

【python】ssim原理簡介及代碼實現

引用參考

https://zh.wikipedia.org/wiki/峰值信噪比
https://en.wikipedia.org/wiki/Peak_signal-to-noise_ratio
https://baike.baidu.com/item/psnr/2925132

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://808629.com/174868.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 86后生记录生活 Inc. 保留所有权利。

底部版权信息