Nodes/comfyui-piq/ContentScore
ComfyUI Node

ContentScore

The style-transfer content loss, repurposed as a metric

By Laurent2916·Created about a year ago·Updated about a year ago· 0
ContentScore
  • image_a
  • image_b
  • content_loss
feature_extractor
replace_poolingfalse
distance
reduction
normalize_featuresfalse

This node is literally a style-transfer loss dressed up as an image metric. ContentScore runs both images through a VGG network and measures how far apart their deep feature activations are - the same ContentLoss that the classic Gatys-style neural style transfer used to keep the subject intact while the style changed. As a standalone score, it answers a very specific question: "does this image have the same content as the reference, ignoring how it's painted?" Lower is better - 0.0 means identical deep features.

It's one of the seventeen nodes in comfyui-piq, Laurent Fainsin's wrapper around the piq library.

How it works. A VGG network (vgg16 or vgg19, your choice of extractor) is used as a frozen feature extractor, and the comparison happens at a mid-level layer (relu3_3 in piq's implementation) - deep enough that it's encoding what's in the picture rather than raw pixels. The feature maps from both images are compared with a distance metric (mse or mae), the per-layer distances are weighted and pooled (reduction - mean gives one score per image), and normalize_features optionally L2-normalizes the features before comparing. replace_pooling swaps VGG's max pooling for average pooling, which makes the features a bit smoother - leave it off by default.

The real gotcha, shared with StyleScore and LPIPS: it downloads VGG weights on first run. The vgg16/vgg19 models are pretrained on ImageNet and torchvision fetches them (~528 MB for vgg16, ~549 MB for vgg19) from pytorch.org on first use, caching in ~/.cache/torch. First run needs internet and patience; after that it's instant.

Inputs a beginner actually sets:

  • image_a / image_b - candidate vs. reference; image_b is ground truth.
  • feature_extractor - vgg16 (default) is fine; vgg19 is deeper and slower for marginal gain.
  • distance / reduction - mse and mean for one comparable number.
  • replace_pooling, normalize_features - leave off unless you're replicating a specific paper setup.

The content_loss output is a FLOAT, lower better.

Installing. ComfyUI Manager, search "comfyui-piq", Install. Or:

cd ComfyUI/custom_nodes
git clone https://github.com/Laurent2916/comfyui-piq.git
pip install -r custom_nodes/comfyui-piq/requirements.txt

piq>=0.8.0 is the entire requirements file; Python 3.12+; repo archived but functional.

The honest take. ContentScore is a niche but sharp tool. Use it when you want to verify that a style transfer or a "paint this in another style" pipeline kept the subject's structure intact - content matches, score low; content drifted, score climbs. It's redundant with LPIPS for general quality checks (LPIPS covers content and low-level stuff in one number), but if you want the content axis isolated, this is the clean way to get it.

Categorypiq

Inputs (7)

NameTypeDefaultDescription
image_aIMAGEInput image
image_bIMAGEReference image
feature_extractorCOMBONeural network for feature extraction
replace_poolingBOOLEANfalseReplace max pooling with average pooling
distanceCOMBODistance metric
reductionCOMBOReduction method
normalize_featuresBOOLEANfalseWhether to normalize extracted features

Outputs (1)

NameTypeDescription
content_lossFLOATContent Loss Based on Deep Features