Image Similarity
How Similar Is It, Really? Scoring Two Images With ResNet
- image_1
- image_2
- is_similiar
- cosine_similarity
Image Similarity answers a question ComfyUI can't otherwise ask: are these two images actually similar, or just close enough that your eye stopped looking? You wire in two images and it hands back a cosine similarity score plus a yes/no "is this over my threshold" boolean. That sounds boring until you need it. Measuring what a denoise change actually did. Checking whether your IP-Adapter or ControlNet run really stayed close to a reference. Deduping a batch of outputs that all look "kind of the same" to you but aren't. It's the quantitative version of a judgment you were making by squinting.
The name is honest: it's one node, no API, no key, no model files to hunt down. The author (ngosset / Norman Gosset, u/phauwk on Reddit) built it in early 2025 after someone on r/comfyui asked for exactly this, and his own framing of the pitch is still the best one - there were already face-similarity nodes around, but they only look at the face. This one scores the whole image, so it's for scene and style similarity, not identity matching.
How it works
Under the hood it's the classic image-search trick. It loads a ResNet pretrained on ImageNet, chops off the final classification layer, and pushes both images through the model to get a feature embedding. The two embeddings are compared with cosine similarity, which lands between -1 and 1 (in practice, almost always above 0 - that's a clue for the threshold discussion below). Both images get resized to 256, center-cropped to 224, and normalized with ImageNet stats first, which is why the whole thing behaves sensibly no matter what resolution your workflow is producing.
The resnet_model dropdown lets you swap ResNet18/34/50/101/152. Default is resnet50, and honestly that's the one to leave it on. Bigger ResNets extract richer features but are slower and heavier; 50 is the usual sweet spot. ResNet18 is there if you're scoring hundreds of images and want speed. You won't feel the difference in quality unless your images are weird.
The inputs and outputs that matter
- image_1 / image_2 - the two
IMAGEtensors you're comparing. Feed one image per input; this node is built for one-at-a-time comparisons. - resnet_model - architecture choice, default
resnet50. - threshold - float from 0.0 to 1.0, default 0.70. This is where people get burned. ImageNet embeddings cluster in a narrow cosine band, so two completely different images can still score 0.5–0.6. A near-identical pair hits ~0.99. That 0.7 default is a guess, not gospel - run a few comparisons you already know the answer to and calibrate.
Outputs: cosine_similarity (the raw FLOAT, wire it into any text display node to see it) and is_similiar (the BOOL). One genuinely annoying detail: that output is spelled is_similiar - typo and all, straight from the code. Match it when you're wiring by name. The node is flagged as an output node, so it can sit at the end of a branch and just report.
Installing it
Easiest path is ComfyUI Manager: search "ImageSimilarity" and install. Or, the old-fashioned way:
cd ComfyUI/custom_nodes
git clone https://github.com/ngosset/ComfyUI-ImageSimilarity.git
Then restart ComfyUI. Nice thing about this one: there's no requirements.txt, nothing to pip install. It only needs torch and torchvision, both of which ship with ComfyUI, so no dependency-conflict roulette (the usual custom-node pain - see the ecosystem notes on how common that is). The one "download" is the ResNet weights, which PyTorch pulls from its own hub on the first run and caches in ~/.cache/torch/hub/checkpoints. ResNet50 is about 100 MB, so the first execution is slower and then it's instant.
Gotchas worth knowing
The model gets rebuilt on every execution rather than cached across runs. For occasional comparisons that's fine; if you're scoring hundreds of images in a loop it adds up. Also, since the embedding comes from an ImageNet-trained model, it's scoring "does a ResNet think these look like the same kind of thing" - great for composition, subject, and scene similarity, mediocre for judging whether a face is the same person. If that's your use case, a face-focused node is the right tool. And if you're using it to verify workflow determinism, remember diffusion is never pixel-identical run to run: treat 0.99+ as a pass, not 1.0.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| image_1 | IMAGE | — | |
| image_2 | IMAGE | — | |
| resnet_model | COMBO | resnet50 | 5 options: resnet18, resnet34, resnet50, resnet101, resnet152 |
| threshold | FLOAT | 0.700–1 | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| is_similiar | BOOL | — |
| cosine_similarity | FLOAT | — |