BuildColorRangeAdvanced (hsv)
For when a percentage knob isn't enough to mask your color
- samples
- HSV_COLOR
- HSV_COLOR
- IR_HUE_MODE
Most color-masking needs are served by a percentage slider. BuildColorRangeHSV covers those. But sometimes the color you're chasing is sneaky - wide, or clipped, or living right at the edge of the hue circle - and you need to define the range by hand. That's what BuildColorRangeAdvanced is for: instead of a knob, you get three expression fields, one each for hue, saturation, and value, and you write the math that turns a set of sampled colors into a lower and upper bound for the mask.
It's honestly a niche tool, and the pack knows it. This is the "advanced" sibling; if you're not comfortable writing little expressions, use BuildColorRangeHSV and skip this one. But if you're doing serious color-key work - green screen cleanup, matching a brand color across inconsistent lighting - the expression language is what lets you encode "wide hue, but clamp saturation hard" as a one-liner.
How it works
You feed it an HSV_SAMPLES object - that comes from the pack's SampleColorHSV node, which you use to collect the pixels you consider "target color." Then each of hue_exp, sat_exp, val_exp is a mini-program evaluated against those samples. The tools available to you:
- quantile helpers:
h_quant2(a, b),s_quant2,v_quant2- get a hue/sat/val interval between two quantiles - stats:
v_median(and the other channel medians), plusto_interval - chainable operators:
.interpolate(...),.scale_by_constant(...)
Each expression must return a [lower, upper] pair. The defaults are already written and they're good - they use a fallback branch that switches behavior when the samples are nearly black or nearly white (the if 2 < v_median < 253 else ... pattern). You mostly edit these rather than start from blank.
The node then fixes the bounds for OpenCV's HSV reality: hue lives 0–180 (not 360), and a range that crosses zero has to be split - which is why there's a third output, IR_HUE_MODE, telling the downstream InRangeHSV node whether to treat the hue as one interval or two. Outputs are HSV_COLOR lower, HSV_COLOR upper, and IR_HUE_MODE, all consumed together by InRangeHSV (or the pack's Color Clip) to build the mask.
Install
Part of bmad4ever/comfyui_bmad_nodes:
cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_bmad_nodes
cd comfyui_bmad_nodes
pip install -r requirements.txt
Restart, or ComfyUI Manager → search comfyui_bmad_nodes. The expressions are evaluated by the pack's simpleeval dependency, so that one in requirements.txt actually matters here. No models.
Gotchas
This node assumes you've read the docs - it's the "❔/advanced" tier, and the README's notes on the expression language are worth an actual read before you start. The sample source matters: garbage in (blurry, mixed-color samples) gives you bounds that only make sense if your expressions account for it. And the IR_HUE_MODE output is not optional - if you forget to wire it to InRangeHSV along with the two colors, hue edges (where masks usually break) will come out wrong.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| samples | HSV_SAMPLES | — | |
| hue_exp | STRING | # hue h_quant2(0, 1).scale_by_constant(16) if 2 < v_median < 253 else to_interval(0, 180) | — |
| sat_exp | STRING | # saturation to_interval(5, 255) if 2 < v_median < 253 else s_quant2(0,1).interpolate(0.2, [0, 255]) | — |
| val_exp | STRING | # value v_quant2(0,1).interpolate(.5, [0, 255]).scale_by_constant(50) if 2 < v_median < 253 else v_quant2(0,1).scale_by_constant(8) | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| HSV_COLOR | HSV_COLOR | — |
| HSV_COLOR | HSV_COLOR | — |
| IR_HUE_MODE | IR_HUE_MODE | — |