Compare two images: PSNR, SSIM and a difference map

Runs entirely in your browser. Your images are never uploaded.

1. Load the two images

Both must have the same width and height. For an upscaler, reduce your original by a whole factor, upscale that copy by the same factor, and compare the result with the original.

Or try a sample: or against the original.

What the numbers mean

PSNR (peak signal-to-noise ratio) measures how far the pixel values are from the reference, on a logarithmic scale in decibels. Higher is closer; identical images have no error, so their PSNR is infinite.

MSE  = mean over every pixel (and every colour channel) of (reference − test)²
PSNR = 10 × log10(255² / MSE)      in dB, for 8-bit images

Every 6 dB means half the error amplitude (a quarter of the MSE). As a rough feel for 8-bit photos: above 40 dB differences are hard to see even side by side, 30 to 40 dB is typical of decent compression or a good 2x upscale, and below 25 dB the changes are obvious. Those bands are a feel, not a standard: the same PSNR can look very different depending on where the error is.

SSIM (structural similarity) compares small windows of the two images in three ways at once: average brightness, contrast, and structure (whether the pixel pattern goes up and down together). It runs from −1 to 1, and 1 means identical. For each 11 × 11 window:

SSIM(x, y) = ((2·μx·μy + C1) · (2·σxy + C2)) / ((μx² + μy² + C1) · (σx² + σy² + C2))
C1 = (0.01 × 255)²,  C2 = (0.03 × 255)²

μ are the window means, σ² the variances, σxy the covariance, all weighted by a Gaussian. The SSIM of the image is the average over every window.

The heat map shows where the differences are. The SSIM map paints each window by how dissimilar it is; the difference map paints each pixel by its largest channel difference. Amplify it to see small differences, which are often invisible at 1x.

Exact settings, so you can reproduce the numbers

Setting Value
Colour values As stored in the file, 8 bits per channel. EXIF orientation is applied; ICC colour profiles are not, and transparency is ignored.
PSNR (RGB) MSE pooled over R, G and B of every pixel; peak 255
PSNR (Y) and SSIM On luma Y = 0.299 R + 0.587 G + 0.114 B (BT.601, full range, not rounded)
SSIM window Gaussian, σ = 1.5, 11 × 11, weights normalised to sum to 1
SSIM constants K1 = 0.01, K2 = 0.03, L = 255; population (not sample) covariance
Image borders Only windows that fit entirely inside the image are averaged; nothing is padded and no border is cropped
Downsampling None

These are the settings of Wang, Bovik, Sheikh and Simoncelli's 2004 paper and its reference code (ssim_index.m), and they match scikit-image's structural_similarity with gaussian_weights=True, sigma=1.5, use_sample_covariance=False, data_range=255. The tool's code is tested against scikit-image values to nine decimal places on every build.

Why your numbers may differ from another tool:

What PSNR and SSIM can and can't tell you

They are good at one question: how close is this image to that one, pixel for pixel? That makes them right for checking compression settings, for spotting an edit that changed more than intended, and for regression tests in an image pipeline.

They are bad at another question: which of two images looks better? The standard example is AI upscaling. A model trained to hit high PSNR learns to output the average of all the plausible answers, which is smooth and slightly blurry. A GAN-based upscaler invents sharp, plausible detail: fur, skin pores, foliage. Its detail is not in the right place pixel for pixel, so it scores lower PSNR and often lower SSIM, even when most people prefer it. Our upscaler baselines show exactly this on real photos.

Other limits worth knowing:

Privacy

Both images are decoded and compared by JavaScript on your device. The computation runs in a Web Worker so the page stays responsive. Nothing is sent to PhotoAIBench or anyone else; you can disconnect from the network after the page loads and the tool still works. Details are on the privacy page.

Limits of the tool

Also available as Markdown.