Spaces:
Sleeping
Sleeping
| """Synthesize a clean microscopy-like image and a degraded (blurred + noisy) version.""" | |
| from __future__ import annotations | |
| import numpy as np | |
| def clean_image(h: int = 256, w: int = 256, seed: int = 0) -> np.ndarray: | |
| """A microscopy-style scene: blobs (cells) + filaments, values in [0, 1].""" | |
| rng = np.random.default_rng(seed) | |
| img = np.zeros((h, w), np.float32) | |
| yy, xx = np.mgrid[0:h, 0:w] | |
| for _ in range(35): # blobs | |
| cy, cx = rng.uniform(0, h), rng.uniform(0, w) | |
| r = rng.uniform(3, 9) | |
| img += rng.uniform(0.4, 1.0) * np.exp(-(((yy - cy) ** 2 + (xx - cx) ** 2) / (2 * r ** 2))) | |
| for _ in range(12): # filaments | |
| y0, x0 = rng.uniform(0, h), rng.uniform(0, w) | |
| ang = rng.uniform(0, np.pi) | |
| for t in np.linspace(0, rng.uniform(20, 60), 200): | |
| y, x = int(y0 + t * np.sin(ang)), int(x0 + t * np.cos(ang)) | |
| if 0 <= y < h and 0 <= x < w: | |
| img[max(0, y - 1):y + 1, max(0, x - 1):x + 1] += 0.5 | |
| return np.clip(img / max(img.max(), 1e-6), 0, 1) | |
| def degrade(clean: np.ndarray, psf_sigma: float = 2.0, peak: float = 40.0, | |
| read_sigma: float = 0.03, seed: int = 1) -> np.ndarray: | |
| """Blur with a Gaussian PSF, then add Poisson (shot) + Gaussian (read) noise.""" | |
| from scipy.ndimage import gaussian_filter | |
| rng = np.random.default_rng(seed) | |
| blurred = gaussian_filter(clean, sigma=psf_sigma) | |
| shot = rng.poisson(np.clip(blurred, 0, None) * peak) / peak # photon noise | |
| noisy = shot + rng.normal(0, read_sigma, clean.shape) # read noise | |
| return np.clip(noisy, 0, 1).astype(np.float32) | |