Inpainting

“Inpainting” means filling in a missing or damaged part of an image so it looks complete again. It’s a built-in capability of SPICEData, reached through its inpaint property. Give spice.inpaint.<method>() a binary mask (a black-and-white image marking which pixels are damaged) and it repairs those pixels in spice.data, changes spice.data in place, and returns spice itself.


spice.inpaint

You don’t need to build any separate object — spice.inpaint is ready to use on any loaded SPICEData:

from juspice.io import load_data

spice = load_data('corrupted.png')
spice.inpaint.telea(mask, radius=3.0)

Since each call returns spice, you can chain several calls in a row by accessing .inpaint again:

spice.inpaint.telea(mask, radius=2.0) \
     .inpaint.biharmonic(other_mask)

Available methods

  • telea() — OpenCV’s Telea fast marching method: fills a hole by working inward from its edge, spreading nearby colors and texture toward the center.

  • navier_stokes() — OpenCV’s Navier-Stokes method: a different, smoother way of doing the same edge-inward fill.

  • biharmonic() — scikit-image’s biharmonic method: solves a smooth mathematical surface through the hole, based on the surrounding pixels.

  • iopaint() — runs the external IOPaint command-line tool (the LaMa model by default), the same background-filling tool standard_augmentations() uses during synthetic-data generation (see Synthetic Data). Needs its own environment — see IOPaint Installation.

  • stable_diffusion() — a generative method: instead of copying nearby pixels, it imagines new content for the hole based on a text prompt you give it, using the Hugging Face diffusers AutoPipelineForInpainting pipeline (diffusers/stable-diffusion-xl-1.0-inpainting-0.1 by default — the same one juspice.stable_diff.StableDiff uses). Because it’s generating new content, results depend on the prompt and are different every time unless you set seed. strength should stay at its default of 1.0 — lower values anchor the result to the already damaged pixels underneath the mask and can leave dark or blurry patches instead of a proper fill. The model loads once per (model_id, device) combination and stays cached for as long as your program runs; the very first call downloads roughly 4-5 GB of model weights to ~/.cache/huggingface/hub/. Needs the dl extra — a matching torch/diffusers/huggingface_hub/transformers/peft set (see Installation).

  • inpaint() — one method that can call any of the above; pass method="telea"|"navier_stokes"|"biharmonic"|"iopaint"|"stable_diffusion".

Reproducibility

Every call made through spice.inpaint is written into DatasetHistory as an inpaint.<method> entry, using the exact values you called it with — including the mask itself, stored as a literal array so the replay script needs nothing else to run. These entries appear in the <stem>.json sidecar file and turn back into plain spice.inpaint.<method>(mask=..., ...) calls when you run to_lines() or to_script() — there’s no separate inpainter object or manual copying involved.

If you’re recording inside a Tracker block, every call is also saved word-for-word in the session’s _history.py file.


See also