Spaces:
Paused
Paused
| """The ONE entrypoint a tool author edits. | |
| `process(file_url, engine, radius, strength)` runs Noise2Void self-supervised | |
| denoising on a noisy 2D image and returns a noisy/denoised/clean summary plus a | |
| report (PSNR/SSIM when the clean ground-truth sidecar is available). | |
| """ | |
| from __future__ import annotations | |
| import os | |
| import numpy as np | |
| from . import n2v, viz | |
| from .io import load_image_from_any | |
| ENGINES = n2v.ENGINES | |
| def _to_gray01(arr: np.ndarray) -> np.ndarray: | |
| a = np.asarray(arr) | |
| if a.ndim == 3: | |
| a = a[..., :3].mean(-1) | |
| a = a.astype(np.float32) | |
| return np.clip((a - a.min()) / max(a.max() - a.min(), 1e-6), 0, 1) | |
| def simulate_full(image_path, engine: str = "fast", radius: int = 2, | |
| strength: float = 1.0) -> dict: | |
| if engine not in ENGINES: | |
| raise ValueError(f"Unknown engine '{engine}'. Choose one of {ENGINES}.") | |
| noisy = _to_gray01(load_image_from_any(image_path)) | |
| clean = None | |
| # Clean ground-truth sidecar, saved next to the baked example as a hidden file | |
| # (leading dot) so it is never mistaken for an input image. | |
| if isinstance(image_path, str): | |
| base = os.path.splitext(image_path)[0] | |
| d, name = os.path.split(base) | |
| for side in (base + "_clean.npy", os.path.join(d, "." + name + "_clean.npy")): | |
| if os.path.exists(side): | |
| try: | |
| clean = np.load(side) | |
| except Exception: # noqa: BLE001 | |
| clean = None | |
| break | |
| res = n2v.analyze(noisy, engine=engine, radius=int(radius), | |
| strength=float(strength), clean=clean) | |
| return {"summary": viz.summary_image(res), "report": res["report"], "res": res} | |
| def process(image_path, engine: str = "fast", radius: int = 2, | |
| strength: float = 1.0) -> tuple[np.ndarray, dict]: | |
| """Returns (noisy/denoised/clean summary RGB, report dict).""" | |
| r = simulate_full(image_path, engine, radius, strength) | |
| return r["summary"], r["report"] | |