cv2.log
For HDR and spectra, not for slapping a 'log look' on 0-255 pixels
- src
- nparray
cv2.log computes the natural logarithm of every element of an array. One input, one output, no parameters. In a colour-grading pipeline you'd use a log curve to stop an enormous dynamic range from crushing everything above mid-grey into white - same reason film and cinema cameras use log encodings. In ComfyUI, where the pack's low-level nodes mostly see 0–255 images, that use case barely exists, and the people who reach for this node expecting a "log look" get something they don't recognise.
Where it does earn its place: anything that produces a huge dynamic range in float. A DFT magnitude spectrum, an optical-flow magnitude, a radiance/HDR map, a depth-derived intensity. Those routinely span four or five orders of magnitude, and a straight min-max stretch turns the whole interesting part into a couple of pixels of near-black. Take the log first and the structure reappears.
How it works
Element-wise ln. Two consequences you have to plan around. ln(0) is negative infinity, and log of a negative number is NaN - and both of those show up immediately in real data, because zero is a perfectly ordinary pixel value. The pack is unusually well-behaved here: non-finite pixels are clamped rather than allowed to poison the scaling when an array is converted for display, and Preview CV Array actively excludes NaN/Inf from its value range and paints them in a marker colour (pure red for the standard palettes) so you can see how many there were - Inspect CV Data counts them for you.
It's also a float-domain operation. Feed it the raw 0–255 integer path and the values it returns are in a range that no ordinary display step will make sense of; go through float instead.
In and out
src is the only input: a ComfyUI IMAGE/MASK, or an NPARRAY. An IMAGE linked straight in gets converted to uint8 BGR at 0–255, and the node is on the pack's per-frame list so a whole IMAGE batch goes through frame by frame.
The output is an NPARRAY called nparray - not an IMAGE, deliberately. The pack only echoes the caller's format for functions whose output is still a displayable picture; a log-transformed radiance map is neither signed-safe nor in range, so it hands you the raw numbers and lets you decide.
The practical chain is therefore: get your data as float (Image → CV Array with dtype: float32, or the float output of cv2.dft / cv2.magnitude / cv2.Sobel with ddepth: CV_32F) → cv2.log → Preview CV Array with render: normalize (or heatmap, which is genuinely the nicest way to read a log spectrum) → and only then CV Array → Image if something downstream needs an IMAGE.
Installing the pack
ComfyUI CV (bmad4ever/comfyui_cv) - ComfyUI 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. Python ≥ 3.12, a V3-API ComfyUI build, one pinned contrib OpenCV wheel, no model downloads. cv2.log is core OpenCV, so it's there on a core-only install too - but the pack as a whole expects contrib, so install the contrib wheel and stop worrying.
Where people get burned
Black or blown-out output. You logged an 0–255 range. log(1) is 0 and log(255) is about 5.5, so almost every pixel lands near the bottom of the range and the few bright ones dominate. If you want a genuine log(1 + x) compression rather than log(x), you need an add-one step upstream - CV Scalar feeding cv2.add gets you a constant vector without hand-typing channels.
NaNs everywhere. Any zero pixel becomes -inf. Expect it, and use Preview CV Array or Inspect CV Data to confirm that's what you're looking at rather than assuming the node misfired.
The displayed result loses its scale. CV Array → Image min-max normalizes float data into 0–255 on the way in, so the picture tells you the shape of the response and nothing about its magnitude. Preview CV Array with color_scale on draws the real min/max as a labelled bar, which is the only way to read a log spectrum without lying to yourself.
Opencv wheel confusion. Unrelated to log, but the pack's most common failure: install a non-contrib opencv-python over the contrib wheel and contrib-dependent nodes vanish silently, because all four wheels share one site-packages/cv2. python tools/repair_opencv_contrib.py --check diagnoses it; --apply fixes it.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| src | NPARRAY,IMAGE,MASK | input array. Accepts a ComfyUI IMAGE/MASK directly (frame 0 of a batch) or an NPARRAY. Arithmetic ops (add, multiply, etc.) process the full IMAGE batch when both inputs have the same batch size. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| nparray | NPARRAY | — |