Blur Detection
Your global sharpness score passed, but the eyes are mush
- image
- blur_score
- blur_map
- interpretation
Here's the failure mode that motivates this node: your image averages out sharp - the histogram looks fine, the mean sharpness score is respectable - but the face is soft, the eyes are smeared, and you only noticed because you zoomed in. A single global number can't see that. Blur Detection looks at the image block by block instead, and hands you a map of exactly where the mush is.
It's part of the ComfyUI-Image-Analysis-Tools pack from ThatGlennD, a small suite of objective image-quality checkers. Nothing here calls a model, downloads weights, or touches your VRAM - it's OpenCV and numpy doing math on pixels, which means it's instant and free to run on every output.
How it works
The image goes grayscale, then gets chopped into a grid of square blocks. Each block gets the classic focus test: the variance of the Laplacian (a second-derivative edge detector). Flat, blurry regions produce tiny variance; crisp detail produces big spikes. The score is the mean of all those block variances, so higher = sharper.
One thing worth knowing, because the README undersells it: the README describes the blur score as a 0–1 fraction of "blurry blocks," but the shipped code actually returns the mean Laplacian variance - a number that lands in the hundreds, not between zero and one. The interpretation string does the normalization for you: under 50 reads "Very blurry," under 150 "Slightly blurry," under 300 "Acceptably sharp," and past that "Very sharp." If you're feeding blur_score into a comparison or a filter, treat it as a relative ranking rather than an absolute quality meter.
The inputs that matter
- block_size (8–128, default 32, steps of 8): the pixel side of each test square. Small blocks (16) catch soft eyes and local motion blur but cost more compute. Big blocks (64+) are fast and good at detecting uniform global blur, and will happily miss a small soft patch. There's a real trade here - this is the input you'll actually fiddle with.
- visualize_blur_map (default on): produces the
blur_mapoutput, a viridis heatmap labeled "Blur Strength (Laplacian Variance)" with a colorbar. Bright regions are sharp, dark regions are blurry. It's a matplotlib render, so it comes back as a normal IMAGE tensor you can preview or save.
Outputs
blur_score (FLOAT), blur_map (IMAGE), and interpretation (STRING) - that last one being a human sentence you can show in a Text Display node or feed into a conditional filter. Blur map previews and the black placeholder that appears when visualization is off are all single-frame tensors; like every node in this pack, only the first frame of a batch is analyzed.
Install
ComfyUI Manager (search "Image Analysis" or the repo name), or the manual route:
cd ComfyUI/custom_nodes
git clone https://github.com/ThatGlennD/ComfyUI-Image-Analysis-Tools
cd ComfyUI-Image-Analysis-Tools
pip install -r requirements.txt
Then restart ComfyUI. The requirements are numpy, opencv-python, matplotlib, scikit-learn, Pillow and torch - you almost certainly already have all of them in a working install except possibly scikit-learn and matplotlib, so this is usually a no-download, no-model install.
Common gotchas
- Nodes don't appear after install? The pack imports every node module at startup, and the Color Harmony Analyzer pulls in scikit-learn at module load. If scikit-learn is missing, the whole pack fails to register, not just that one node. In the Windows portable build:
python_embeded\python.exe -m pip install scikit-learn. - Import error about
comfy_api? This pack is written against ComfyUI's newer declarative node API. On a stale install it errors at load; updating ComfyUI first fixes it. - Batches: only the first frame is scored, so don't use this to vet every frame of a video - pipe frames through one at a time instead.
Where people actually reach for it: catching soft eyes in a face-focused workflow, flagging motion blur, and comparing CFG or sampler settings that produce subtly softer outputs. It won't tell you why something is blurry, but it'll tell you where - and that's usually the hard half.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| block_size | INT | 328–128 | — |
| visualize_blur_map | BOOLEAN | true | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| blur_score | FLOAT | — |
| blur_map | IMAGE | — |
| interpretation | STRING | — |