Black Background Scanner
Your subject's already on black — this node finds it, flattens it, and cleans it up
- image
- scanned_image
- detection_mask
The other two nodes in harishcmgit/comfyui_ds look for a page among cluttered surroundings. BlackBackgroundScanner is built for a much more specific situation: you've already got your subject on a black background - a product shot, a scanned slide, a photo of an object on a backdrop - and you just want it isolated, straightened, and cleaned up.
It earns its place because it doesn't need edges. Edge detection is the weak point of the normal document scanner: if your subject has no crisp boundary against a black backdrop, Canny has nothing to grab. This node instead uses the most reliable signal available - the background is black. Everything brighter than the threshold is the subject.
How it works
The mechanism, straight from the source:
- Convert to grayscale and apply a simple binary threshold at
background_threshold. Pixels darker than the threshold are background; everything else is candidate subject. - Clean the resulting mask with a 5×5 close (twice) then open (once) - this fills small holes in the subject and drops specks of noise.
- Find the largest external contour.
- Approximate it to a quadrilateral - it tries loosening the polygon approximation until it gets four points, then falls back to the minimum-area rotated rectangle if that never happens.
- Perspective-crop to that quad (same warp as the other nodes), then run the enhancement.
Everything is CPU-only OpenCV - no model, no API, no downloads.
The inputs that matter
image- your shot, batched if you like.enhancement-clahe(default),sharpening,flat_field, ornone. CLAHE is a good default for texture preservation;flat_fieldhelps when the backdrop isn't evenly lit.background_threshold- the brightness cutoff, default 30, range 10–100. If the subject's dark regions are getting clipped into the background, raise it. If a gray backdrop is bleeding in and masking part of the subject, lower it. It's the one knob you'll actually touch.return_mask- when true, the second output shows the binary detection mask so you can see exactly what got classified as subject.
Outputs: scanned_image (the straightened, enhanced subject) and detection_mask (the black-and-white segmentation). When return_mask is off the mask output is still there - just an all-black tensor, so don't mistake that for a bug. If you do want the mask, it's genuinely useful: it's a ready-made alpha channel or inpainting region.
Installing it
Search comfyui_ds in ComfyUI Manager, or:
cd ComfyUI/custom_nodes
git clone https://github.com/harishcmgit/comfyui_ds
Restart ComfyUI. Just opencv-python and numpy as dependencies (torch is ComfyUI's), no model files. The README's pip install -r requirements.txt doesn't match the shipped repo - there's no requirements.txt in it - so install OpenCV directly if it's missing.
Gotchas
Two things to know. First, the none enhancement option doesn't actually skip enhancement - the code falls through to the sharpening function when it hits an unknown name, so "none" is really "sharpening with extra steps." If you want truly raw output you're out of luck here.
Second, this node assumes the background is darker than the subject and stays that way. Hard shadows that drop below the threshold get treated as background and can carve chunks out of your subject; a subject with black parts will lose them. That's what return_mask is for - check it before you trust the crop. And like its siblings, failure is silent: if something goes wrong it hands back your input unchanged, so if the output looks identical to the input, something failed.
It's also worth the same caveat as any young node: this pack is a single commit with no community track record, and custom nodes run arbitrary code on your machine. The source is short - skim it once and you'll know exactly what you're running.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| enhancement | COMBO | clahe | 4 options: clahe, sharpening, flat_field, none |
| background_threshold | INT | 3010–100 | — |
| return_mask | BOOLEAN | false | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| scanned_image | IMAGE | — |
| detection_mask | IMAGE | — |