NMS
How your detector stops drawing fifty boxes on one dog
- boxes
- scores
- keep_indices
Every real object detector fires way more boxes than it needs - a dozen overlapping rectangles all pointing at the same dog, each with a confidence score. Non-Maximum Suppression is the thing that collapses them into one clean box, and CdlNms is ComfyDL's textbook-clean implementation of it. If you've built a detection pipeline in this pack (anchor boxes in, class probabilities out), this is the node that makes the output actually presentable.
This is a direct port of the nms function from Dive into Deep Learning, the textbook the whole pack is built on. It's a great way to finally internalize what NMS does, because you can watch it happen on a real image step by step.
How it works
The algorithm is refreshingly simple, and the source makes it visible:
- Sort all boxes by score, best first.
- Take the top box, keep it.
- Compute IoU between it and every remaining box; drop any that overlaps it more than
iou_threshold. - Repeat with the next-best surviving box.
That's it. Greedy, fast, and surprisingly effective. The node returns the indices of the boxes that survived - not the boxes themselves - so you keep the mapping back to your original array.
The inputs that matter
boxes-[N, 4]corner-format boxes(x1, y1, x2, y2).scores- a matching confidence score per box.iou_threshold- the only widget, default 0.5. Lower it toward 0.3 and you suppress more aggressively (fewer boxes, risk of merging distinct objects); raise it toward 0.7 and you keep more overlap.
Where people get burned: the IoU threshold default of 0.5 is the classic value, but if your boxes are small or your objects are dense, 0.5 can merge two things sitting close together. When you see one label swallow a neighbor, nudge the threshold up rather than assuming the model is broken.
Output
keep_indices - a torch.int64 tensor of the surviving box indices, sorted by score. In the ComfyDL world that's a cdlTensor, so it flows into the pack's other detection and visualization nodes. A typical end-to-end: Multibox Detection already runs NMS internally, so this standalone node is for the case where you have raw boxes + scores - say, thresholded class probabilities you want to turn into final detections - and you want the surviving picks to feed Show BBoxes.
Installing ComfyDL
ComfyDL is one pack with a light install - its only extra dependency is matplotlib:
cd ComfyUI/custom_nodes
git clone https://github.com/Cynthia-lxx/ComfyDL
cd ComfyDL && pip install -r requirements.txt
Restart ComfyUI and look under the ComfyDL → ObjectDetection menu. ComfyUI Manager users can just search "ComfyDL". No models to download - nothing here touches a checkpoint.
The trap to remember
NMS is per-image and operates on a flat [N, 4] tensor. If your boxes come out of a batch-shaped tensor with a leading dimension, squeeze it first, or you'll be sorting IoUs against a whole batch's worth of boxes as if they were one image. It's the single most common shape mistake with this node, and the error messages won't tell you why - you'll just get nonsense indices.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| boxes | TENSOR | — | |
| scores | TENSOR | — | |
| iou_threshold | FLOAT | 0.500–1 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| keep_indices | TENSOR | — |