Nodes/ComfyUI template matching/TemplateMatching (template matching)
ComfyUI Node

TemplateMatching (template matching)

Find your logo anywhere in an image — no model, no weights, just OpenCV

By wentao-uw·Created 2 years ago·Updated 2 years ago· 1
TemplateMatching (template matching)
  • rgbimage
  • rgbtemplate
  • MASK
methodTM_CCOEFF_NORMED
matched_thresh0.80
rot_range0,360
rot_interval180
scale_range50,200
scale_interval10
rm_redundanttrue
minmaxtrue

Screenshot with a logo you want to swap out. A product photo where the same widget appears in every shot. A UI mock with a button you want to inpaint away. All of those are the same ask - "find region X in image Y and give me a mask" - and it's a solved, boring, fast problem in classic computer vision. It's also the one thing core ComfyUI doesn't ship. This node ports OpenCV's matchTemplate into the graph: feed it an image and a little template, get back a MASK showing every place the template matched. No weights to download, no VRAM, no API key. It runs in milliseconds.

What it actually does

Mechanically it's the textbook algorithm, dressed up with rotation and scale search. Both images get converted to grayscale, then for every combination of scale and rotation the template is resized/rotated and slid across the image computing a similarity map. Spots above your threshold survive, overlapping duplicates get merged, and the survivors are drawn as white bounding boxes on a black mask the same size as your input image.

That mask is the whole point. Wire it into an inpaint node to replace a logo, into a crop to regenerate just that region, or into anything else that eats a MASK. It's the deterministic, old-school alternative to YOLO-style detection nodes - nothing to train, nothing to mislabel, and it will never hallucinate a match that isn't there. The trade-off is the flip side of that determinism: it only finds things that visually resemble the template.

The inputs that matter

  • rgbimage / rgbtemplate - the search area and the patch you're hunting. The template must be the same data type and not larger than the image; the README says so, and in practice a too-big template just never matches.
  • method + matched_thresh - TM_CCOEFF_NORMED at 0.8 is the sane starting point. Leave the TM_SQDIFF pair alone unless you enjoy pain: those are inverted (lower = better), so a 0.8 threshold finds nothing.
  • rot_range / rot_interval, scale_range / scale_interval - the search space. Defaults are 0,360 degrees and 50,200 percent.
  • rm_redundant / minmax - merge nearby duplicate hits, and keep only the single best point per rotation/scale combo.

Where people get burned

The rotation search is a half-lie. In the source, parse_points_list only draws boxes for matches found at angles between 0 and 5 degrees - anything found rotated gets thrown away before the mask is built. And with the default rot_interval of 180, the loop only ever tries angles 0 and 180 anyway. In practice this node is a scale-invariant, upright detector: it'll find your target at 50–200% size, but if the object is actually rotated in the frame you get an empty mask and zero error messages. Don't tune rot_interval to 1 hoping for rotation support; that's where your runtime goes and it still won't produce rotated boxes.

Two more gotchas. It's single-image only - the code calls squeeze(0) on the input, so feed one image at a time, not a batch, or cvtColor will choke on a 4D array. And remember the threshold is a confidence dial: at 0.8 you get clean hits, drop to ~0.6 and you start catching lookalikes. Runtime is roughly scale steps × rotation steps matchTemplate passes, so the interval knobs are where your seconds go.

Installing it

ComfyUI Manager is the easy path: search for "ComfyUI template matching", install, restart. Or manually:

cd ComfyUI/custom_nodes
git clone https://github.com/wentao-uw/ComfyUI-template-matching

The requirements.txt lists opencv-python, numpy, matplotlib, and torch. The heavy two are already in any working ComfyUI install, so the practical missing piece is just opencv-python - and since nothing is version-pinned, the README's pip3 install -r requirements.txt is a no-op on the packages you already have rather than a risk to your CUDA torch build. It's a lightweight, one-commit port from cozheyuanzhangde/Invariant-TemplateMatching, and it shows: no dependencies beyond that list, no model files.

If you get an empty mask, the debug loop is short: is the template upright, within the searched scale range, and visually close to the target? Is the threshold too high? For everything else, it's the kind of tool that just quietly works.

Categorytemplate_matching

Inputs (10)

NameTypeDefaultDescription
rgbimageIMAGE
rgbtemplateIMAGE
methodCOMBOTM_CCOEFF_NORMED6 options: TM_CCOEFF, TM_CCOEFF_NORMED, TM_CCORR, TM_CCORR_NORMED, TM_SQDIFF, TM_SQDIFF_NORMED
matched_threshFLOAT0.80
rot_rangeSTRING0,360
rot_intervalINT180
scale_rangeSTRING50,200
scale_intervalINT10
rm_redundantBOOLEANtrue
minmaxBOOLEANtrue

Outputs (1)

NameTypeDescription
MASKMASK