ContentScore
The style-transfer content loss, repurposed as a metric
- image_a
- image_b
- content_loss
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_bis ground truth.feature_extractor-vgg16(default) is fine;vgg19is deeper and slower for marginal gain.distance/reduction-mseandmeanfor 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.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| image_a | IMAGE | Input image | |
| image_b | IMAGE | Reference image | |
| feature_extractor | COMBO | Neural network for feature extraction | |
| replace_pooling | BOOLEAN | false | Replace max pooling with average pooling |
| distance | COMBO | Distance metric | |
| reduction | COMBO | Reduction method | |
| normalize_features | BOOLEAN | false | Whether to normalize extracted features |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| content_loss | FLOAT | Content Loss Based on Deep Features |