PSNR SSIM LPIPS Image Quality
Three fidelity lenses for restored images: pixel error, structural match, and learned perceptual distance.
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 and mean squared error , the peak signal-to-noise ratio is , 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 with : dB. Quarter the error to and the score rises to dB, so a 6.02 dB lift always means the error fell by a factor of four.
For SSIM, compare against on a 0 to 255 scale. The means are and , where denotes the window average. The population variances are and , where denotes spread around the mean, and the covariance , because never moves from its mean. With the standard constants and , which stabilize the division:
One deviant pixel in four costs about five SSIM points, while the same patch pair would show a modest MSE of . 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.02MSE 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 while a normalized one uses , 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 to your bit depth before comparing anything, and distrust tables that never state it.
The Quick Version
- PSNR equals 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.