BinarizeImageUsingOtsu
The threshold picks itself
- images
- IMAGE
BinarizeImageUsingOtsu is the lazy person's binarization node, and I mean that as a compliment. Where its sibling BinarizeImage makes you hand-tune a threshold value, this one has no threshold input at all - it computes the cutoff automatically from the image's histogram using Otsu's method, a thresholding algorithm from 1979 that's still the default answer in OpenCV for exactly this problem. You feed it an image, you get black-and-white output, and you never touch a dial.
The theory is refreshingly sensible. Otsu's method looks at the histogram of grayscale values and finds the threshold that best separates the pixels into two classes - the split that minimizes the combined variance within each class (equivalently, maximizes the variance between them). In plain terms: it finds the valley between two brightness peaks. If your image is naturally two-tone - dark text on white paper, a dark subject on a light background - that valley is usually obvious, and Otsu lands right in it. That's exactly the situation where hand-tuning a threshold is busywork.
How it works
In the source it's one line of OpenCV after the usual grayscale conversion:
_, binary = cv2.threshold(gray_uint8, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
The 0 threshold you pass in is ignored when the THRESH_OTSU flag is set - OpenCV computes the real cutoff from the histogram and applies it. The binary result is expanded back to three channels, and any alpha channel from the input is preserved.
images(IMAGE) - the image or batch. That's the only input. No threshold, no mode, nothing to configure.
Output is a single IMAGE tensor of pure black and white, same dimensions as the input.
When it shines - and when it flops
Reach for this on bimodal images, and it will feel like magic: scanned documents, screenshots of text, logos, icons, diagrams - anything where the brightness distribution has two clean peaks. That's where Otsu beats manual tuning every time, because the "right" threshold is genuinely different per image and this node finds it fresh on each frame (so it also survives batch variation, where one fixed threshold across a whole batch is almost always wrong somewhere).
Where it fails is the flip side: if there is no clear valley in the histogram, the "best" split is still computed, and it's arbitrary. Photographs, gradients, busy scenes with continuous tonal range - Otsu will happily pick some threshold and produce a speckly mess. That's not a bug in the node; it's the algorithm's fundamental assumption showing. And it's worth repeating the general binarization warning: a hard threshold always destroys soft edges, so use this for masks and line art, not for anything that needs to stay feathered.
Installing
Same pack, same install as everything else here:
cd ComfyUI/custom_nodes
git clone https://github.com/keit0728/ComfyUI-Image-Toolkit
Restart ComfyUI, or install "ComfyUI-Image-Toolkit" through ComfyUI Manager. The only dependency is opencv-python==4.11.0.86 - pinned, which can make the install pause while pip reconciles an existing OpenCV. No models, no GPU, CPU-only, batch-friendly.
Gotchas
The main one is expectation management: "automatic" thresholding is not "good" thresholding on every image, so check the output on photographic content before you trust it. And the usual pack caveats apply - this is a tiny anonymous project (Japanese author, comments in Japanese, last commit mid-2025), and the README's clone URL is a placeholder with your-username in it; the real repo is keit0728/ComfyUI-Image-Toolkit. Simple algorithm, clean implementation, no support desk. For a one-line OpenCV call, that's fine.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | Images to binarize. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |