Image PSNR
The dB number every model card quotes, on your canvas
- image_a
- image_b
- psnr_db
- mse
You've seen "PSNR: 31.5 dB" in a model card and nodded along without knowing what it actually means. This node is the five-minute cure. KU_ImagePSNR takes two images, computes the Peak Signal-to-Noise Ratio between them, and prints the answer on the node. It's one of three metrics in the comfyui-image-metrics pack - a small teaching collection by Dr. Nobutaka Kuroki at Kobe University - and it's the one you'll reach for when you want a single, boring, comparable number for "how close is this to the original."
What it's for
Any time you produce a modified copy of an image and want to score the damage: downscale-and-upscale round-trips, a reconstruction through a VAE, a compression step, a tiled pipeline that might be leaving seams. The pack's own example workflow is the classic: load an image, downscale it 4x, upscale it back with bilinear, bicubic, and lanczos, then feed all three against the original. You get three dB numbers telling you which resampler loses the least. That's the whole job, and it's a job people keep doing by eye when a metric would settle it - the same "cheap deterministic primitive before expensive guessing" instinct this whole ecosystem runs on.
How it works
PSNR is the mean squared error in disguise. ComfyUI's IMAGE tensor is floats in the 0..1 range, so with a peak of 1.0 the formula is 10 * log10(1 / MSE) in dB. Every halving of the error adds about 3 dB, so the scale is intuitive once you think of it as "how many decimal places of agreement." Bigger is better; identical images score about 100 dB (the code clamps MSE with a tiny epsilon so you don't get literal infinity). Two details make the number reproducible rather than accidental: the metric is computed per image pair and then averaged across the batch - the convention benchmark papers use over a test set, not pooling every pixel together - and it deliberately assumes the standard 0..1 IMAGE range.
Inputs and outputs
Just two required inputs, both IMAGE: image_a and image_b. They must be the same shape. There are no knobs, which is the point.
- psnr_db (
FLOAT) - the score in dB. Wire it into anything that takes a FLOAT, or just read it. - mse (
FLOAT) - the underlying mean squared error, handed to you for free since PSNR computes it internally anyway.
The node is an output node, so it runs and shows you the value even if nothing is plugged into its outputs. That's a nice touch for a metric node - you don't have to invent a text display.
Installing it
Via ComfyUI Manager, search "comfyui-image-metrics" (pack title "ComfyUI-Image-Metrics"), or:
cd ComfyUI/custom_nodes
git clone https://github.com/NobutakaKuroki/comfyui-image-metrics
Restart ComfyUI and look under KULab → Metrics. That's the whole install: no requirements to pip-install, no model downloads - it's pure tensor math on torch, which ComfyUI already ships.
Where people get burned
The shape check is strict - a batch of 4 images against a batch of 1 errors out, so keep batch sizes matched. And remember the batch-averaging convention: you get one number for the whole batch, with no way to isolate a single pair. The real trap is trusting PSNR alone. It's a pixel-error metric and it will happily hand a blurry, structurally wrong image a decent score because blurred pixels are numerically closer. That's exactly why the pack also ships SSIM - run both and look for disagreement, which is the honest signal.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| image_a | IMAGE | — | |
| image_b | IMAGE | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| psnr_db | FLOAT | — |
| mse | FLOAT | — |