Skip to content
AI360XpertBeta

PSNR SSIM LPIPS Image Quality

Three fidelity lenses for restored images: pixel error, structural match, and learned perceptual distance.

PSNR, SSIM, and LPIPS score the same restored patch differently, because pixel error, structure, and perception disagree on purpose.
PSNR, SSIM, and LPIPS score the same restored patch differently, because pixel error, structure, and perception disagree on purpose.

Why Does This Exist?

Restored images need numbers, but pixel error alone rewards blur. Shift a sharp edge by one pixel and the squared error screams, yet any viewer prefers it over a blurry smear with a smaller error. So restoration papers report three lenses at once: PSNR prices mean squared error, SSIM prices local structure, and LPIPS prices distance in deep features. This page covers all three formulas, one fully recomputed toy patch, and the traps of reading any single number alone. Denoising pipelines that consume these scores live in image denoising.

Think of It Like This

Ruler, tracing, and art teacher

You hand in one drawing and get three grades. The ruler measures how far each line sits from the answer, to the millimeter. Tracing paper checks whether the shapes line up, ignoring small shifts. The art teacher steps back and judges whether the two pictures feel alike.

PSNR is the ruler, SSIM is the tracing, LPIPS is the teacher. The grades disagree on purpose, and together they say more than any one alone.

It stops at taste. The teacher still grades like the average viewer of their training set, so all three can bless an image your users dislike.

How It Actually Works

For maximum pixel value MM and mean squared error MSE\text{MSE}, the peak signal-to-noise ratio is PSNR=10log⁡10(M2/MSE)\text{PSNR} = 10 \log_{10}(M^2 / \text{MSE}), in decibels, where higher is better. SSIM compares two windows through luminance, contrast, and structure terms and returns a value up to 1, where 1 means identical and higher is better. LPIPS feeds both patches through a fixed network (AlexNet or VGG in the original), normalizes the feature maps, and averages squared differences, so it is a distance where lower is better and 0 means identical.

Worked toy patch

Take M=1M = 1 with MSE=0.01\text{MSE} = 0.01: PSNR=10log⁡10(1/0.01)=10×2=20\text{PSNR} = 10 \log_{10}(1 / 0.01) = 10 \times 2 = 20 dB. Quarter the error to 0.00250.0025 and the score rises to 10log⁡10(400)≈26.0210 \log_{10}(400) \approx 26.02 dB, so a 6.02 dB lift always means the error fell by a factor of four.

For SSIM, compare x=[100,100,100,104]x = [100, 100, 100, 104] against y=[100,100,100,100]y = [100, 100, 100, 100] on a 0 to 255 scale. The means are μx=101\mu_x = 101 and μy=100\mu_y = 100, where μ\mu denotes the window average. The population variances are σx2=3.0\sigma_x^2 = 3.0 and σy2=0.0\sigma_y^2 = 0.0, where σ2\sigma^2 denotes spread around the mean, and the covariance σxy=0.0\sigma_{xy} = 0.0, because yy never moves from its mean. With the standard constants C1=(0.01×255)2=6.5025C_1 = (0.01 \times 255)^2 = 6.5025 and C2=(0.03×255)2=58.5225C_2 = (0.03 \times 255)^2 = 58.5225, which stabilize the division:

SSIM=(2×101×100+6.5025)(0+58.5225)(1012+1002+6.5025)(3.0+0.0+58.5225)≈0.9512\text{SSIM} = \frac{(2 \times 101 \times 100 + 6.5025)(0 + 58.5225)}{(101^2 + 100^2 + 6.5025)(3.0 + 0.0 + 58.5225)} \approx 0.9512

One deviant pixel in four costs about five SSIM points, while the same patch pair would show a modest MSE of 4.04.0. LPIPS needs a real network, so treat it qualitatively here: identical patches score exactly 0, and a blurred patch scores farther from the original than a sharp shifted one, which is the opposite of the PSNR verdict.

Code

import math

def psnr(mse: float, peak: float = 1.0) -> float:    """Peak signal-to-noise ratio in dB from mean squared error."""    return 10 * math.log10(peak ** 2 / mse)

print(round(psnr(0.01), 2), round(psnr(0.0025), 2))# -> 20.0 26.02

MSE 0.01 gives 20 dB and quarter error gives about 26.02 dB, replaying the worked patch. SSIM and LPIPS need real windows and networks, so they stay qualitative on this page.

Watch Out For

Shipping on PSNR while images look worse

Blur kills squared error, so a mushy output can outscore a sharp one with texture. The symptom is a rising dB curve beside outputs your own eyes reject. Don't ship on PSNR alone: gate releases on LPIPS and blind side-by-side looks next to it.

Comparing decibels across different peaks

An 8-bit pipeline uses M=255M = 255 while a normalized one uses M=1M = 1, and the two PSNR values are not comparable numbers. The symptom is a "state of the art" table where one row quietly used the friendlier peak. Fix MM to your bit depth before comparing anything, and distrust tables that never state it.

The Quick Version

  • PSNR equals 10log⁡10(M2/MSE)10 \log_{10}(M^2 / \text{MSE}) in decibels, and higher is better.
  • SSIM prices local structure with 1 as perfect, and one pixel in four off costs about five points here.
  • LPIPS is deep-feature distance with 0 as identical, and lower is better.
  • MSE 0.01 gives 20 dB while 0.0025 gives about 26.02 dB at peak 1.
  • Report all three, because a pixel win can look worse to a viewer.