D-DFFNet Defocus Blur Detection
Defocus Blur Detection in ComfyUI
- image
- mask
Your segmentation models are really good at finding things - a person, a product, a stray hair. What if the thing you want masked out isn't an object at all, but a state of the photo? That soft, dreamy out-of-focus background from a shallow depth of field, or the bokeh you'd swear your subject is drowning in. BiRefNet and friends won't help you there, because blur isn't a subject. D-DFFNet Defocus Blur Detection is the niche tool that does exactly one thing: look at an image and hand you a mask of every region that's out of focus.
It's a narrow, academic-grade wrapper around the D-DFFNet model from the paper "Depth and DOF Cues Make A Better Defocus Blur Detector" (ICME 2023, Jin et al.), and it ships in the small ComfyUI-D-DFFNet pack from MoRanYue. Fair warning up front: this is a genuinely obscure node - effectively zero community footprint, no auto-downloading models, and a dropdown that greets you with "[No models found]" until you feed it weights. But if you need to know where the blur is, there basically isn't another ComfyUI node doing it.
How it works
The model is a depth-aware defocus detector. A ResNeSt-101 backbone extracts features at four scales, four RFB (receptive field block) modules grab multi-scale context, and an aggregation head with spatial attention fuses everything into a per-pixel blur probability. The "D" in D-DFFNet is the interesting part: during training the network learned depth priors through knowledge distillation from MiDaS - the same Intel depth estimator the KB's depth essay tracks from its SD 2.0 depth2img days. Depth cues help a lot here, because a sharply-focused near object against a blurred far background is a depth structure, not just a texture one.
At inference, you feed plain RGB. The depth side outputs (side5–side8 in the checkpoint) are a training-only detail; that's why the code loads weights with strict=False and shrugs off missing keys. Every image gets resized to 320×320 internally, run through the net, then the predicted mask is resized back to your original resolution. Batches work fine - feed it N images, get N masks.
The inputs and outputs that matter
Only three knobs, so this is the easy part:
- image - any
IMAGEtensor (BHWC, float32, [0,1]). - model_name - a dropdown listing
.pth/.ptfiles inComfyUI/models/dffnet/. This is where the "[No models found]" placeholder lives until you add weights. - threshold - default 0.5. Leave it at 0.5 and you get a hard binary mask (pixel in or out). Set it to 0 and you get the raw probability map instead - soft edges you can feather, blur, or use as a compositing alpha. For photo work I'd actually start at 0; the binary mask from a 320×320 model can have crunchy edges, and the soft map is more useful.
The single output, mask, is a standard ComfyUI MASK (BHW, float32, [0,1]) - wire it into anything that takes a mask: MaskToImage, inpainting, an alpha channel for compositing, or a MaskBlur before you use it.
Installing it
Two paths, both simple:
- ComfyUI Manager: search "ComfyUI-D-DFFNet" and install.
- Manual:
Then restart ComfyUI.cd ComfyUI/custom_nodes git clone https://github.com/MoRanYue/ComfyUI-D-DFFNet.git
The actual work is the models. The README lists six Google Drive downloads (three D-DFFNet, three plain DFFNet, trained on different splits of CUHK-TR-1/2 and DUT-TR), and you must drop one into a folder that doesn't exist yet:
mkdir -p ComfyUI/models/dffnet/
# put your .pth here, then hit Refresh in the node
Good news on dependencies: there's no requirements.txt and nothing exotic - just PyTorch ≥ 2.0 and numpy, which every ComfyUI install already has. The refactored code even stripped out the resnest.torch dependency. You will never pip-install anything for this pack.
Where people get burned
The classic sequence: install, restart, see "[No models found]", and assume it's broken. It's not - the dffnet model folder simply doesn't exist until you create it and add a .pth. The Google Drive step is also the part that rots; if a link is dead, pick another training variant, they're interchangeable in practice.
One console warning you'll see: loading a plain DFFNet checkpoint (no depth branch) prints "Missing depth side outputs" for side5–side8. That's expected and harmless - the README says so and the code says so. Don't go hunting for the "correct" checkpoint.
And set expectations: this detects blur, it doesn't fix it. It's a mask source, not a ControlNet preprocessor or a bokeh generator. Pair it with sharpening or inpainting on the masked region, or invert the mask to keep your in-focus subject untouched. For defocus-specific masking, that's the whole job - and it's the only node in ComfyUI doing it.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| model_name | COMBO | 1 options: [No models found] | |
| thresholdopt | FLOAT | 0.500–1 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| mask | MASK | — |