Nodes/ComfyUI Multi-Analysis Heatmaps/Image Analysis (SSIM/LPIPS/FFT/ΔE2000)
ComfyUI Node

Image Analysis (SSIM/LPIPS/FFT/ΔE2000)

See where your upscaler actually changed the image — without trusting your eyes

By Justify87·Created 12 months ago·Updated 7 months ago· 7
Image Analysis (SSIM/LPIPS/FFT/ΔE2000)
  • image_a
  • image_b
  • ssim_heatmap
  • dssim_heatmap
  • ms_ssim_heatmap
  • lpips_heatmap
  • diff_abs_heatmap
  • residual_visual
  • fft_orig
  • fft_upscaled
  • fft_diff
  • ssim_text
  • lpips_text
  • deltaE2000_heatmap
  • L_diff_heatmap
  • a_diff_heatmap
  • b_diff_heatmap
  • gradient_diff_heatmap
  • edge_iou_heatmap
  • edge_iou_text
  • wavelet_band_diff_heatmap
  • denoiser_residual_visual
  • roundtrip_diff_heatmap
align_mode
color_map
invert_ssimtrue
ms_scales3
enable_lpipsfalse
edge_percentile0.85
wavelet_levels3
denoise_sigma2.0
denoise_gain2.0
roundtrip_scale0.50
roundtrip_kernel

Every "which upscaler is best" argument on r/comfyui ends the same way: two people staring at 2x crops, disagreeing about which one looks sharper, with zero evidence. This node is the evidence. Feed it two images - original vs. upscaled, denoised vs. raw, seed A vs. seed B - and it spits out a wall of heatmaps showing where they differ, not just by how much.

The name is a lie in the best way: there's no API, no model download, no key. It's pure torch math (plus an optional VGG16 for the LPIPS map), and the author says so outright - the README calls it "vibe-coded" and warns the heatmaps are heuristics, not verdicts. Bright ≠ bad, dark ≠ good. Read the maps as "here is where the difference lives," not "this is where it broke."

How it works

Drop in an image_a and image_b, and the node runs a dozen comparison methods in one pass: SSIM/DSSIM/MS-SSIM structural maps, per-pixel absolute difference, a signed residual (what B added vs. removed), FFT magnitude spectra plus their difference, ΔE2000 color distance in Lab space (with separate L*, a*, b* channels), Scharr gradient difference, an edge IoU map, Haar wavelet band difference, a Gaussian high-pass "denoiser residual" that isolates noise/texture, and a round-trip stability map that downscales B, re-upscales it, and diffs against itself. Everything runs in fp32 under no_grad, so it's fast and VRAM-lean - milliseconds for a typical image.

That's the pitch and the trap at once: it produces 21 outputs, and the node UI looks like a firehose. Don't wire them all to PreviewImage. Pick the two or three that match what you're doing.

The inputs that matter

You'll touch maybe five of the thirteen:

  • image_a / image_b - your two images. Order matters for the signed residual (bright = added by B, dark = removed).
  • align_mode - resize_b_to_a (default) just resizes B to fit A. center_crop_to_min and pad_to_max exist for mismatched sizes; you almost never need them for A/B upscale pairs.
  • invert_ssim - default true, and keep it there. It flips SSIM so bright = different, matching every other heatmap's convention. Turn it off only if you want the "bright = similar" academic look.
  • color_map - jet (default) is easier to read than grayscale; pick grayscale if you're saving maps for a paper.
  • enable_lpips - the one that costs you. Defaults to false; flip it on and the node builds a VGG16 from torchvision (first run downloads the ImageNet weights, so you need internet once) and computes a perceptual map. Fair warning: the source calls it "LPIPS approx," and it is - a VGG16-feature approximation, not the officially calibrated LPIPS package. The number in lpips_text is directional, not a publishable score. The map is still genuinely useful as a "what would a human notice" view.

Everything else - ms_scales, edge_percentile, wavelet_levels, denoise_sigma, denoise_gain, roundtrip_scale, roundtrip_kernel - is tuning. Defaults are fine to start.

The outputs worth wiring up

  • ssim_heatmap and dssim_heatmap - your daily drivers. Instant structural overview of where the upscaler moved things.
  • diff_abs_heatmap - raw pixel difference; bright where the values changed even if it's imperceptible.
  • denoiser_residual_visual - the interesting one for diffusion upscalers. Bright = new noise/texture B didn't have, which is exactly how hallucinated detail shows up.
  • roundtrip_diff_heatmap - bright = areas that don't survive a downscale/re-upscale round trip; your shortcut to "robustness, not just looks."
  • ssim_text / edge_iou_text - the only numbers; tiny string outputs you can show in a text node or log.

Wire whichever maps you want into PreviewImage or SaveImage.

Install

Through ComfyUI Manager, search "Multi-Analysis Heatmaps" and install. Or manually:

cd ComfyUI/custom_nodes
git clone https://github.com/Justify87/ComfyUI-Multi-Analysis-Heatmaps

Restart ComfyUI. There are no extra dependencies - no requirements.txt, nothing beyond the torch/torchvision ComfyUI already ships. The only download is VGG16's weights if you ever enable LPIPS.

Where people get burned

The README is stale in places, and the docs rot here shows: it lists a resid_gain option and fft_log_eps that don't exist in the shipped v3.0.3 node UI, and documents denoise_sigma at 1.0 when the code defaults to 2.0. If you can't find a knob the README promises, that's why. It also recommends the lanczos round-trip kernel while the code only offers bicubic, bilinear, and area. Follow the actual node inputs, not the table.

The other trap: with resize_b_to_a the node silently squashes a bigger B down, and a misaligned comparison produces a beautiful heatmap that means nothing. Make sure your two images are the same subject and roughly the same scale before you trust any of this. The node is a compass, not a judge - it points at where things changed, and the interpretation is on you.

CategoryImage/Analysis

Inputs (13)

NameTypeDefaultDescription
image_aIMAGE
image_bIMAGE
align_modeCOMBO3 options: resize_b_to_a, center_crop_to_min, pad_to_max
color_mapCOMBO2 options: jet, grayscale
invert_ssimBOOLEANtrue
ms_scalesINT31–5
enable_lpipsBOOLEANfalse
edge_percentileFLOAT0.850.5–0.99
wavelet_levelsINT31–4
denoise_sigmaFLOAT2.00.5–5
denoise_gainFLOAT2.00.1–10
roundtrip_scaleFLOAT0.500.25–0.95
roundtrip_kernelCOMBO3 options: bicubic, bilinear, area

Outputs (21)

NameTypeDescription
ssim_heatmapIMAGE
dssim_heatmapIMAGE
ms_ssim_heatmapIMAGE
lpips_heatmapIMAGE
diff_abs_heatmapIMAGE
residual_visualIMAGE
fft_origIMAGE
fft_upscaledIMAGE
fft_diffIMAGE
ssim_textSTRING
lpips_textSTRING
deltaE2000_heatmapIMAGE
L_diff_heatmapIMAGE
a_diff_heatmapIMAGE
b_diff_heatmapIMAGE
gradient_diff_heatmapIMAGE
edge_iou_heatmapIMAGE
edge_iou_textSTRING
wavelet_band_diff_heatmapIMAGE
denoiser_residual_visualIMAGE
roundtrip_diff_heatmapIMAGE