Badge Master Registration (DAELab)
Dragging a generated badge back onto your design grid
- design_image
- design_foreground_mask
- candidate_image
- candidate_foreground_mask
- base_render
- transform
- contour_iou
- boundary_error
- diagnostic
- registration_valid
What it is and why you'd reach for it
Generative models do not respect your coordinate system. Ask for a front-on badge and you'll get one, but it'll be 1.5% larger than the design and rotated a quarter of a degree, and the whole thing will be sitting two pixels up and left of where it started. That's invisible until the moment you try to use a mask.
Because the entire DAELab badge workflow is mask-driven: you select a region in design coordinates and apply it to render coordinates. Two pixels of drift and your edit lands on the neighbouring enamel field. Badge Master Registration is the node that measures and corrects the drift: it finds the similarity transform (translate, uniform scale, small rotation) that puts the generated badge's silhouette back on the design silhouette, applies it, and refuses to continue if the fit isn't good enough.
How it works
It's a coarse-to-fine brute-force search, and it's refreshingly honest about being one. Both silhouettes are downsampled so the longer side is 256px (nearest-neighbour throughout, since these are masks). Then it searches a small grid: seven rotation angles across ±max_rotation_degrees (default ±3°), three scale offsets around a base scale estimated from area and bounding box, and a 3×3 grid of ±4px translation nudges. It scores every combination by IoU between the design mask and the warped candidate mask, keeps the best, and then scales that 2×3 matrix back up to full resolution.
The warp to full resolution uses Lanczos, and pads with the candidate's estimated background colour - median of the sampled content or, if you supplied candidate_foreground_mask, the median of the whole image. Without a supplied mask, the candidate's foreground is inferred by colour distance from the border median, morphology-cleaned, and reduced to its largest connected component. That single-component step is what stops a stray watermark or a bit of shadow at the canvas edge from wrecking the fit.
Then it measures honestly: contour_iou for the overlap, and a symmetric boundary_error in pixels via distance transforms between the two outlines. With enforce_threshold on - the default - anything below minimum_iou (0.97) raises Badge master registration rejected.
Inputs and outputs that matter
design_image and design_foreground_mask come from the canvas/design side. candidate_image is the raw generative output, and the node will bicubic-resize it to the design canvas if the model returned a different size - unlike the composite node, this one is forgiving about size. minimum_iou, max_rotation_degrees, max_scale_delta and background_tolerance are the search bounds; widen them only if you understand the search is brute force and every axis costs linear time.
Optional candidate_foreground_mask is worth wiring if anything upstream can produce one: it removes the colour-distance guess from the pipeline and makes the IoU number trustworthy.
Outputs: base_render is the registered, corrected image and is what every later stage should consume. transform is a JSON string with the matrix, rotation, scale, IoU and boundary error per batch item - feed it into Badge Edit State Save's registration_info so a resumed session carries the same mapping. contour_iou (worst in batch) wires into Badge Edit Mask Validator's registration_iou. boundary_error and diagnostic are QA; the diagnostic encodes registered mask in red, design mask in green, overlap in blue, which makes a systematic offset obvious at a glance.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/TeutonicMepheles/ComfyUI-DAELab-Custom-Nodes-Library
Restart. Manager search by pack title is equivalent. This node needs OpenCV - the pack's requirements.txt lists only document-parsing libraries, so pip install opencv-python-headless if the node never appears in the menu.
Common issues
Badge master registration rejected. Either the model re-designed the badge (a shape change, not a shift) or it rendered at a perspective the ±3°/±10% search can't reach. Looseningminimum_iouto 0.93 to get moving is fine for testing; shipping at that value means your masks are approximate.- The candidate came back at a strange aspect ratio. It gets resized to the design canvas first, which can stretch a genuinely non-square result. Check the upstream prompt's framing language before blaming this node.
- Registration passes but edits still land off.
max_scale_deltaof 0.10 is a hard clamp on the search. A model that rendered the badge 20% large will fit the clamp, score mediocrely, and if your threshold is loose, sail through. Readtransform'sscalefield. - IoU is a single number. It's the minimum across the batch. A batch of four where one image slipped gives you that image's score, which is the behaviour you want but occasionally confusing when three look perfect.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| design_image | IMAGE | — | |
| design_foreground_mask | MASK | — | |
| candidate_image | IMAGE | — | |
| minimum_iou | FLOAT | 0.9700–1 | — |
| max_rotation_degrees | FLOAT | 3.000–10 | — |
| max_scale_delta | FLOAT | 0.100–0.3 | — |
| background_tolerance | FLOAT | 0.080–1 | — |
| enforce_threshold | BOOLEAN | true | — |
| candidate_foreground_maskopt | MASK | — |
Outputs (6)
| Name | Type | Description |
|---|---|---|
| base_render | IMAGE | — |
| transform | STRING | — |
| contour_iou | FLOAT | — |
| boundary_error | FLOAT | — |
| diagnostic | IMAGE | — |
| registration_valid | BOOLEAN | — |