Nodes/ComfyUI CV/CV HDR Exposure Fusion (Mertens)
ComfyUI Node

CV HDR Exposure Fusion (Mertens)

The HDR look without the exposure times

By bmad4ever·Created 3 months ago·Updated 14 days ago· 1
CV HDR Exposure Fusion (Mertens)
  • image
  • fused
◄contrast_weight1.0►
◄saturation_weight1.0►
◄exposure_weight1.0►

Four bracketed photos of the same scene: sky blown out in one, shadows crushed in the others. Exposure fusion blends them into a single image where every region comes from whichever frame exposed it best - no exposure times to type, no response curve to recover, no separate tonemapping pass. Feed a batch in, get a display-ready image out.

It's Mertens' exposure fusion (the MergeMertens algorithm in OpenCV) as a node in bmad4ever's ComfyUI CV (bmad4ever/comfyui_cv, a fork of Gerold Meisinger's opencv-comfyui). Alongside its two siblings in the hdr family - CV HDR Merge to Radiance and CV HDR Tonemap - it covers the more forgiving half of the HDR pair: the half where the output is an ordinary 0–1 image, not a float radiance map.

How it works

Per pixel, per frame, it scores three things: well-exposedness (is this pixel mid-tone rather than clipped or crushed), local contrast, and saturation. Those scores become weights, the weights get smoothed into a consistent map so you don't get patchwork seams, and the frames are blended accordingly. The classic result is a scene with sky detail and shadow detail, with a characteristic slightly-flat, illustrative look - which is the actual criticism of exposure fusion as a style, and it's fair.

contrast_weight, saturation_weight and exposure_weight (each 0–5, default 1) are the three terms' multipliers. exposure_weight is the heart of it: the tooltip's words are that low values let blown highlights and crushed shadows leak in, because you've stopped preferring the correctly-exposed frame for that pixel. Setting any weight to 0 removes the term entirely. If your result looks washed and grey, you've likely pushed exposure weighting up while contrast has nothing to grab - a textured, well-focused bracket fuses far better than a soft one.

Inputs and outputs

image is a batch of registered exposures - same scene, same framing, tripod or pre-aligned. That's the assumption worth respecting: the algorithm has no idea your frames moved. Handheld brackets will fuse into mush at the edges, and the pack ships CV Align MTB and CV Align MTB To Reference for exactly that, in the same family, before this node. Median-threshold-bitmap alignment is cheap and it's designed for exposures, so there's no reason to skip it.

Output is a single fused image, ordinary 0–1 IMAGE. No exposure times required, no float array, nothing else to wire up - which is the entire appeal.

Install

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

Or find ComfyUI CV in ComfyUI Manager. Python ≥ 3.12 and a ComfyUI recent enough for the V3 node API. workflows/15_hdr_playground.json is a genuinely useful example: it fuses the same four JPEGs three times with different weight settings so you can see what each term does, and it shows the MTB alignment stage with before/after previews.

Common issues

Ghosting at the edges. Either the frames weren't registered, or something moved between exposures (foliage, a person, water) and the fusion picked different frames either side of it. Alignment fixes the camera; nothing fixes the moving object. Weight toward exposure and accept it, or mask the region.

A flat, slightly plastic result. That's the algorithm's signature, not a bug. Fusion is a local operation: it never builds a real radiance map, so it can pull detail out of highlights but can't reconstruct the scene's actual dynamic range. If you want the honest HDR version - linear light, values well past 1.0, your choice of tone curve - merge to radiance and tonemap instead. It's more work and it's the right answer for anything you're going to grade.

Frames in the wrong order. Doesn't crash, doesn't error, just fuses with the weights applied to the wrong exposures. Stack bracketed over/under frames in a deliberate order and check the first frame preview.

Only two exposures. It runs, and you get a mild blend with little to gain. Three or more well-spaced stops is where this earns its place.

Categoryimage/CV/hdr

Inputs (4)

NameTypeDefaultDescription
imageIMAGEBatch of registered exposures of the same scene (tripod, or pre-aligned).
contrast_weightFLOAT1.00–5Emphasis on locally contrasty (in-focus, textured) pixels. 0 ignores contrast.
saturation_weightFLOAT1.00–5Emphasis on saturated (vivid) pixels.
exposure_weightFLOAT1.00–5Emphasis on well-exposed (mid-tone) pixels - the heart of the fusion; low values let blown highlights and crushed shadows leak in.

Outputs (1)

NameTypeDescription
fusedIMAGEDisplay-ready fused image (0..1 IMAGE).