Search by Image
Find every shot that looks like this one
- index
- model
- image
- results
Search by Text needs you to describe what you're after. Search by Image skips the describing: give it a reference image and it finds every indexed photo that's visually or semantically similar - same subject, same scene, same lighting, same composition. It's reverse image search, done locally, against your own library.
The mechanism is pleasingly symmetrical with Search by Text. The reference image goes through the same EMBEDDING_MODEL and comes out as a vector; FAISS finds the index vectors closest to it; you get back SEARCH_RESULTS with paths and similarity scores. Because the query and the index were produced by the same model at the same resolution, the comparisons are apples-to-apples - which is also the node's biggest trap (see below).
The input choice that matters
You have two ways to supply the reference, and the node accepts either:
- image (
IMAGE) - a ComfyUI image tensor. This is the flexible path: you can search by something you just generated, or by any image already flowing through your graph. The node converts it, saves it to a temp file, embeds it, and cleans up after itself. - image_path - a direct path to an image file on disk. Faster, no tensor plumbing, and handy if you're building a batch over files.
The rest are the standard knobs: top_k (default 50), min_score, result_type, and instruction. Output is a single results SEARCH_RESULTS handle.
Install
Same pack install as every node here - ComfyUI Manager (search "Semantic-Search") or clone https://github.com/EricRollei/Semantic-Search into custom_nodes, pip install the requirements, restart, nodes under Eric/SemanticSearch. No API keys - this is a purely local operation.
Where people get burned
- Resolution mismatch between query and index. The model's
max_resolutionapplies to both indexing and querying, but if you reindexed at a higher resolution after searching at a lower one, your query image gets shrunk to the model's current max pixels while the index vectors were built at the old size. Match them, or similarity scores will be consistently weird. Rebuilding the index after changingmax_resolutionis the fix. - Expecting pixel-level "same image" search. This finds semantically similar images. A crop of the same photo scores high; a different photo with the same subject and mood also scores high. If you want exact-duplicate detection, that's a different tool - this one is about "show me everything like this."
- Searching with a low-res or heavily-watermarked reference. The embedding model sees what the reference shows. A tiny, compressed thumbnail yields a fuzzy query vector and fuzzy results; feed it the best-quality version of the reference you have.
- No image and no path wired. The node returns empty results if both
imageandimage_pathare missing - there's no error, just nothing. Easy to do when you're rebuilding a workflow from scratch.
Search by Image is the pack's "oh, this is the one I mean" node - the fastest route from "I've seen a shot like this before" to actually finding it.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| index | SEMANTIC_INDEX | — | |
| model | EMBEDDING_MODEL | — | |
| imageopt | IMAGE | — | |
| image_pathopt | STRING | — | |
| top_kopt | INT | 501–500 | — |
| min_scoreopt | FLOAT | 0.000–1 | Minimum score threshold (0-1). Results below this score are filtered out. |
| result_typeopt | COMBO | all | Filter results by media type: all, images, videos, documents, or media (images+videos) |
| instructionopt | STRING | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| results | SEARCH_RESULTS | — |