PSNR is most easily defined via the mean squared error (MSE). Given a noise-free m×n monochrome image I and its noisy approximation K, MSE is defined as:
The PSNR (in dB) is defined as:
Here, MAXI is the maximum possible pixel value of the image. When the pixels are represented using 8 bits per sample, this is 255. More generally, when samples are represented using linear PCM with B bits per sample, MAXI is 2^B−1.
In the formula for PSNR, the value of R is decided by the format of the image. If the image is an 8 bit image, R = 255. If the image is expressed using floating point numbers, R = 1.
MSE = ∑ ∑ ( [n1[i]-n2[i]] ) ^ 2 / m * n
///n1 is the original image, n2 the comparable image, m and n are the image size
PSNR = 10 log₁₀ ( MAX ^ 2 / MSE )
///MAX is the maximum possible pixel value of the image
///For 3D signals (colored image), your MSE needs to sum all the means for each plane (ie: RGB, YUV and etc) and then divide by 3 (or 3 * MAX ^ 2).
For color images with three RGB values per pixel, the definition of PSNR is the same except the MSE is the sum over all squared value differences (now for each color, i.e. three times as many differences as in a monochrome image) divided by image size and by three. Alternately, for color images the image is converted to a different color space and PSNR is reported against each channel of that color space, e.g., YCbCr or HSL.
For colour images, the MSE is taken over all pixels values of each individual channel and is averaged with the number of colour channels. Another option may be to simply perform the PSNR over a converted luminance or grayscale channel as the eye is generally four times more susceptible to luminance changes as opposed to changes in chrominance. This approximation is left up to the experimenter.
close all;
clear all;
clc;
%PSNR的计算
old=imread('carrier.bmp');
%old=rgb2gray(old);
new=imread('compute.bmp');
%new=rgb2gray(new);
[h,w]=size(old);
img=double(old);
imgn=double(new);
B=8; %编码一个像素用多少二进制位
MAX=2.^B-1; %图像有多少灰度级
MES=sum(sum((img-imgn).^2))/(h*w); %均方差
averageMES=sum(MES(:))/3;
PSNR=20*log10(MAX/sqrt(averageMES)); %峰值信噪比
The mean squared error (MSE) for our practical purposes allows us to compare the “true” pixel values of our original image to our degraded image. The MSE represents the average of the squares of the "errors" between our actual image and our noisy image. The error is the amount by which the values of the original image differ from the degraded image.
The proposal is that the higher the PSNR, the better degraded image has been reconstructed to match the original image and the better the reconstructive algorithm. This would occur because we wish to minimize the MSE between images with respect the maximum signal value of the image.
When you try to compute the MSE between two identical images, the value will be zero and hence the PSNR will be undefined (division by zero). The main limitation of this metric is that it relies strictly on numeric comparison and does not actually take into account any level of biological factors of the human vision system such as the structural similarity index. (SSIM)
#calculate_psnr.py
import numpy as np
def calculate_psnr(img1, img2, max_value=255):
""""Calculating peak signal-to-noise ratio (PSNR) between two images."""
mse = np.mean((np.array(img1, dtype=np.float32) - np.array(img2, dtype=np.float32)) ** 2)
if mse == 0:
return 100
return 20 * np.log10(max_value / (np.sqrt(mse)))
#############################第2种代码
import numpy
import math
import cv2
original = cv2.imread("original.png")
contrast = cv2.imread("photoshopped.png",1)
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))
d=psnr(original,contrast)
#d= cv2.PSNR(original,contrast)
print(d)
########################################第三种
from math import log10, sqrt
import cv2
import numpy as np
def PSNR(original, compressed):
mse = np.mean((original - compressed) ** 2)
if(mse == 0): # MSE is zero means no noise is present in the signal .
# Therefore PSNR have no importance.
return 100
max_pixel = 255.0
psnr = 20 * log10(max_pixel / sqrt(mse))
return psnr
def main():
original = cv2.imread("original_image.png")
compressed = cv2.imread("compressed_image.png", 1)
value = PSNR(original, compressed)
print(f"PSNR value is {value} dB")
if __name__ == "__main__":
main()
参考:
https://en.wikipedia.org/wiki/Peak_signal-to-noise_ratio
https://blog.csdn.net/u012193330/article/details/42426271
Python 计算彩色图像信噪比https://blog.csdn.net/u013185349/article/details/85122008