Nodes/ComfyUI DocRes/DocRes Restore
ComfyUI Node

DocRes Restore

Five document-repair jobs behind one dropdown

By zjkhurry·Created 22 days ago·Updated 21 days ago· 1
DocRes Restore
  • model
  • image
  • image
◄taskdewarping►

Half the internet's answer to "my scanned page looks bad" is to throw it at an image model and prompt harder - and you can see why, because restoration as a category is one of the most popular things people do with Stable Diffusion. The catch is that a diffusion model has no idea the letters matter. It will happily invent a plausible-looking word into the middle of your paragraph.

DocRes Restore does the unglamorous version: one Restormer network, five classical document-repair tasks, no prompt, no invention. It doesn't make your page prettier. It makes it legible.

One model, five tasks, and how that's even possible

The task dropdown offers dewarping (the default), deshadowing, appearance, deblurring, and binarization. What's slightly unusual is that the first four all run through the same weights. There's no head swap and no per-task checkpoint.

The trick is the input. The network takes six channels: your three RGB channels, plus a three-channel prompt map computed from the image with cheap classical CV. That prompt encodes which job you asked for - a Sauvola threshold mask for binarization, an edge/blur prompt for deblurring, illumination-ish prompts for deshadowing and appearance - so the conditioning arrives as extra image planes rather than as a different architecture. That's how one set of 58 MB weights covers five jobs without retraining.

What each one actually does:

  • dewarping is the odd one out. It first runs MBD, a separate segmentation net, to find the page and mask everything else to black, then uses the mask plus a base coordinate ramp as the prompt and predicts a dense flow field - a per-pixel "where did this pixel come from" map at 256px, blurred 15 times to smooth it, then applied with cv2.remap. Geometry, not pixels.
  • deshadowing and appearance regress a shading/illumination field and divide it out of the original. That's why they're so gentle on text - nothing is synthesised, a lighting estimate is cancelled.
  • deblurring is a straight image-to-image pass over the padded input.
  • binarization is a two-channel softmax and an argmax: clean black and white, no grey.

Inputs and output

image - the distorted scan, straight from LoadImage.

task - one of the five above. This is the only real decision.

model - from DocRes Loader. It has to be that bundle; feeding anything else raises "model input must come from the DocRes Loader node", which is a clear enough error for once.

The single output is image, and the design intent is that you chain: one Restore node per stage, each feeding the next. Order matters and the sane order is geometry first, shading second, threshold last:

LoadImage ▶ DocRes Restore (dewarping) ▶ DocRes Restore (deshadowing) ▶ DocRes Restore (appearance) ▶ DocRes Restore (binarization) ▶ SaveImage

Because the loader is shared, that five-node chain is still one model in memory.

Install

Manager: search DocRes. Manual:

cd ComfyUI/custom_nodes
git clone https://github.com/zjkhurry/comfyui-docres.git
pip install -r comfyui-docres/requirements.txt

einops, opencv-python, scikit-image, safetensors - only scikit-image is new on a standard install. Weights auto-download to comfyui-docres/weights/: 58 MB for the backbone, and 227 MB for mbd.safetensors, which only dewarping needs. That second download catches people out mid-run.

Where people get burned

The 227 MB stall. Your first dewarping run downloads MBD with no progress indicator. It looks like a hang. It isn't.

Big scans. The pack's own notes cite a 2634x2096 page as the reference hard case. Everything runs fp16 and the code empties the backend cache after every task precisely because the caching allocator would otherwise hold a couple of GB of dead blocks reserved - on Apple silicon, where the GPU shares system RAM, chained nodes will march the machine into swap without that. If you OOM, downscale the scan or split the page; you're not going to make a 20 MP page comfortable by fiddling with settings.

Binarizing too early. A threshold pass on thin or faded text is unforgiving - the pack replicates the single output channel across RGB, so you get hard black and white and nothing in between. Deblur first if the text is mushy. And binarize last: the other four tasks all prefer grayscale input.

Expecting it to fix a nice page. Run appearance on an already-clean image and you'll often get something washed out or over-eager. These are repair tasks. A decent scan doesn't need repairing.

Categoryimage/DocRes

Inputs (3)

NameTypeDefaultDescription
modelDOCRES_MODEL—
imageIMAGE—
taskCOMBOdewarping5 options: dewarping, deshadowing, appearance, deblurring, binarization

Outputs (1)

NameTypeDescription
imageIMAGE—