Nodes/ComfyUI CV/cv2.sortIdx
ComfyUI Node

cv2.sortIdx

Rank Things Without Losing Track of Which Is Which

By bmad4ever·Created 3 months ago·Updated 14 days ago· 1
cv2.sortIdx
  • src
  • nparray
◄flagsSORT_EVERY_ROW | SORT_ASCENDING►

Sorting values is easy; keeping the association between a value and the thing it describes is the part that actually bites. cv2.sortIdx gives you the ordering as indices - same shape as the input, each entry the position of the element that belongs there - which is exactly what you need when you want the top three matches, the strongest responses, or the best-scoring candidate for each detection row, and you still need to know which one you're pointing at.

It's the index-returning half of the pair; cv2.sort returns the sorted values and nothing else. Both live in ComfyUI CV (bmad4ever/comfyui_cv), and for graph work the index version is usually the one you want, because a value on its own is a dead end - you can't look anything up with it.

Inputs

  • src - an NPARRAY, single-channel data. No IMAGE or MASK link: sorting a picture is not a thing. Scores, measured values, descriptor distances, histogram counts - those are the inputs.
  • flags - the same four-way combo as cv2.sort: SORT_EVERY_ROW | SORT_ASCENDING by default, plus descending, plus the column-first variants. The axis choice decides whether you're ranking within each row of a table or within each column, and the value is a bitfield, hence one dropdown rather than two.

One output: nparray - the indices, same shape as the input. These are 0-based positions within each sorted line, so after an ascending row sort the first entry tells you which column held the smallest value.

What you do with indices

This is the node that makes arrays navigable in a graph. Feed the output into CV Take By Index - the pack's lookup-table indexing node - to pull the matching entries out of another array: the same ordering applied to a parallel table of labels, or the top-k of a distance matrix, or the winning candidate's coordinates. That combination (rank here, gather there) is how you express "pick the best one" without a loop node, which matters because ComfyUI graphs don't loop.

Typical jobs: all-pairs descriptor matching where you need the nearest, not just the distances (CV Embedding Match gives you the matrix, this gives you the winner); per-row ranking of template scores; ordering a set of candidate detections before truncating to the top few; and knowing the column index of a peak you found elsewhere. And again, for the single global best element with its location, cv2.minMaxLoc hands you both value and position directly - reach for that before building a sort.

Install

Manager → search ComfyUI CV, or:

cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
pip install "opencv-contrib-python-headless~=5.0.0.93"

Restart ComfyUI. Needs Python ≥ 3.12 and a recent ComfyUI on the V3 node API. No models - this is a CPU microsecond operation.

Where people get burned

Axis confusion. Column-first sorting when you meant row-first yields a valid index array that points at the wrong things. Check shapes with Inspect CV Data when a ranking looks scrambled; it's a two-second diagnosis.

Indices are per-line, not global. After sorting a 10x5 array by rows, indices run 0–4 in each row - they're positions within that row. Feeding a row-local index into a flat lookup gives you the wrong element. CV Reshape Array to a single line first if you want global indices.

Dangling the indices. The index array is the useful output and it's easy to leave it unconnected while wiring the values. If your "top scoring match" node is producing conclusions with no provenance, this is why.

Assuming the indices match a different array's shape. They index into whatever array you gathered from, which is usually the input you sorted, not the sorted output. That's the whole point - but it's easy to get backwards once when a graph grows.

Contrib-wheel collisions. The four OpenCV distributions share one site-packages/cv2; installing a non-contrib wheel over the contrib build silently leaves contrib-backed nodes out of the menu, with no error. tools/repair_opencv_contrib.py --check diagnoses, --apply repairs.

Categoryimage/CV/low-level/cv2 S

Inputs (2)

NameTypeDefaultDescription
srcNPARRAYinput single-channel array. A data array (points / matrix), NOT an image - only an NPARRAY link is accepted here.
flagsCOMBOSORT_EVERY_ROW | SORT_ASCENDINGoperation flags that could be a combination of cv::SortFlags

Outputs (1)

NameTypeDescription
nparrayNPARRAY—