Nodes/MKRShift_Nodes/Histogram Scope
ComfyUI Node

Histogram Scope

A proper waveform readout, rendered as an image

By criskb·Created 7 months ago·Updated 5 months ago· 0
Histogram Scope
  • image
  • mask
  • image
  • mask
  • histogram_info
settings_json{"histogram_mode":"rgb_overlay","bins":128,"contrast":1.25,"fill_opacity":0.3,"normalize_mode":"peak","mask_feather":12.0,"invert_mask":false}

Grading blind is how you end up with crushed shadows or a clipped sky you didn't notice until you exported. Histogram Scope is the MKRShift node that puts a real histogram on your graph canvas - not as a separate viewer or a hidden preview, but as a plain image output you can wire straight into a Save node or look at in the UI. Same idea as a camera's histogram, same reason to trust it: numbers don't lie, and this one shows you where your pixels actually are.

It lives in MKRShift Nodes/Color/Analyze, the pack's inspection lane alongside x1Heatmap and x1HueBandScope. Heatmap shows you where values live in the frame; the scope nodes show you how much of each value exists overall. Two different questions, and you'll want both if you're doing any real grading in ComfyUI.

How it works

The node bins the image's luminance (and color channels) into a count per value level, then renders that distribution as a drawn image - essentially plotting the histogram you'd see in any editor, but as pixels you can route around the graph. The knobs, all in one settings_json string:

  • histogram_mode - rgb_overlay (channels overlaid) or other composite modes for how the RGB curves combine.
  • bins (default 128) - how many value buckets. More bins = finer detail, noisier; fewer = smoother, coarser.
  • contrast (1.25) - stretches the vertical scale of the plot so small populations don't vanish.
  • fill_opacity (0.3) - fills under the curve; lower keeps it a clean line.
  • normalize_mode (peak) - scales the tallest bin to full height. Keeps the shape readable when one value dominates.

The practical workflow

Wire your image in, take the image output, and run it to a preview or save it alongside your grade. The mask output and the histogram_info string are the extras: the mask reflects the histogram (a luma-based mask derived from the analysis), and the info string reports the resolved settings. Honestly, for most people the scope image is the whole point - it's the cheapest possible "am I clipping?" check, and it costs zero generation time.

Use it the way you'd use any scope: glance at it before you grade, not after. If the histogram is slammed against the right wall, you know highlights are clipping and can reach for the pack's x1HighlightRollOff before you even start pushing curves. That loop - look, then act, then look again - is what scopes are for, and this node puts it in-graph instead of in a separate app.

Installing it

cd ComfyUI/custom_nodes
git clone https://github.com/criskb/MKRShift_Nodes

then restart, or search MKRShift_Nodes in ComfyUI Manager. No pip requirements, no model downloads - this is pure numpy histogram math.

One caveat: the output is a rendered plot image, so don't feed it back into the pipeline expecting the original frame - that's what the mask output is for if you need analysis-driven masking. And remember normalize_mode: peak rescales per image, so comparing two frames' histograms means comparing shapes, not absolute heights. If you need a stable scale across a sequence, drop the normalize contrast instead.

CategoryMKRShift Nodes/Color/Analyze

Inputs (3)

NameTypeDefaultDescription
imageIMAGE
settings_jsonSTRING{"histogram_mode":"rgb_overlay","bins":128,"contrast":1.25,"fill_opacity":0.3,"normalize_mode":"peak","mask_feather":12.0,"invert_mask":false}
maskoptMASK

Outputs (3)

NameTypeDescription
imageIMAGE
maskMASK
histogram_infoSTRING