CV Find Absent Color (Lab)
Pick an annotation colour that can't hide in the picture
- image
- color_rgb
- color_name
- color_hex
- distance
- found
Here's the problem this node solves, and it's a more common one than the name suggests: you're drawing a bounding box, a mask outline or a crosshair on an image, and the colour you picked happens to be a colour that's already all over the picture. Green boxes over a forest. Red lines over a tomato. The annotation is technically there and practically invisible. CV Find Absent Color (Lab) hands you a colour that cannot be confused with anything in the frame - the CSS named colour that is furthest, in L*a*b*, from every pixel you gave it.
Why you'd reach for it
It is a visualization helper, and the pack is unusually disciplined about having those as separate nodes - the data nodes never draw, you choose what gets rendered. This one picks the ink. Practical wiring:
- Feed an image, take
color_hex(aCOLORsocket) and drop it into any colour picker input -CV Color From Hexor the drawing nodes' colour fields. - Take
color_namewhen you want the choice to be readable in a log or a text overlay ("rebeccapurple" is a lot more useful in a filename than#663399). - Take
color_rgbwhen the consumer wants three floats - it's a CV Scalar-shapedNPARRAY, exactly the shapeCV Scalaremits, so it broadcasts into the low-levelcv2.*drawing wrappers (this is the pack's answer to "cv2 needs a Scalar and ComfyUI has no Scalar type").
The secondary use is palette analysis: point it at a stylised render, and the absent colour it returns tells you which region of colour space your image never visits. That's a diagnostic, not a workflow, but it's a fast one.
How it works
The image is converted to OpenCV's L*a*b*, and each of the 148 CSS named colours is measured against it: for every candidate, the distance to its nearest pixel. Candidate colours within threshold of any pixel count as present. Of the rest, the one with the greatest distance wins. If nothing is absent, you still get the furthest colour back, but found flips to false so a downstream switch knows the answer is a judgement call rather than a guarantee.
Distance is selectable: Euclidean (L2) is the classic ΔE-style metric; Manhattan (L1) sums per-channel differences and is easier to reason about channel by channel. Both operate in 8-bit Lab space, so L is 0–255 and a/b are offset like OpenCV's, not the −128…127 lab you might be picturing.
The inputs that matter
image- the frame(s) to analyse. A batch is fine, and a colour counts as present if it appears in any frame, so one pass over a whole shot covers your whole video.metric-Euclidean (L2)by default. Leave it unless you have a reason.threshold- how close a pixel has to be before a colour is "present", default 10, range 0–255 in half steps. At 0 only an exact match counts, and given there are 148 candidates you'll likely find one absent and get afound = trueyou shouldn't fully believe. Raise it - 15–30 is where the answer starts to mean "nothing in the image is remotely like this colour".max_pixels(optional, advanced) - per-frame cap on pixels searched, default 200 000, applied as an even stride. It's the reason a 4K frame doesn't take a second. The flip side is in the tooltip and it's real: a colour present in only a handful of pixels can fall between strides and be reported absent. If your subject is small, raise it.
Outputs: color_rgb (NPARRAY), color_name (STRING), color_hex (COLOR), distance (FLOAT), and found (BOOLEAN). distance is the winner's distance to the nearest image pixel - pair it with found in a conditional if you want the graph to react to a borderline result.
Install
ComfyUI Manager → search ComfyUI CV, or clone the repo into ComfyUI/custom_nodes and restart:
cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
The pack needs opencv-contrib-python-headless~=5.0.0.93, Python 3.12+ and a ComfyUI new enough for the V3 node API. No models.
Traps
- A tiny
thresholdplus genuine colour variety →found = false. That's the node telling you the image already contains something close to every CSS colour, which usually means you set the threshold too low or the image is a colour-chart-like scene. - CSS colours are a coarse palette. They're web colours, not a full Lab gamut. On a monochrome image you'll get something wildly saturated, which is what you want for an overlay and absolutely not what you want if you were hoping for a "subtle" annotation.
- It doesn't know the annotation colour from other overlays. Give it the original image, not one you already drew on, or the previous overlay's colour counts as present.
- Values are returned in RGB order even though the pipeline carries BGR, because the image arrives as RGB in ComfyUI. The pack is explicit about this in the tooltip; if you hand
color_rgbto a rawcv2drawing wrapper that expects BGR, expect swapped channels.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | Input image. A batch is accepted: a color counts as present when it occurs in ANY frame. | |
| metric | COMBO | Euclidean (L2) | Distance in L*a*b* space: Euclidean (L2) is the classic delta-E; Manhattan (L1) sums the channel differences and is cheaper to reason about per channel. |
| threshold | FLOAT | 10.00–255 | A CSS color counts as present when any pixel is within this Lab distance (OpenCV L*a*b* uint8 space: L 0-255, a/b 0-255). 0 = only an exact match counts; larger = more colors considered present. |
| max_pixelsopt | INT | 2000001000–100000000 | Per-frame cap on pixels searched, applied as an even deterministic stride so big images stay fast. A color present in only a few pixels below this stride may be missed - raise it for large canvases. |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| color_rgb | NPARRAY | CV Scalar (r, g, b) float64 of the chosen CSS color (the image arrives in RGB, so the color is returned in the same order). |
| color_name | STRING | CSS name of the chosen color, lowercase (e.g. 'rebeccapurple'). |
| color_hex | COLOR | Hex as #RRGGBB uppercase, typed as a COLOR socket - links straight into ComfyUI color-picker inputs (e.g. 'CV Color From Hex'). |
| distance | FLOAT | Lab distance of the chosen color to its nearest image pixel (its distance to the existing colors). |
| found | BOOLEAN | True when an absent color exists (distance above the threshold). False when every CSS color is present - the color is then still the furthest of the 148 from the existing colors. |