FlashReFocus / flashrefocus /image_io.py
ming0531's picture
Use the flashrefocus package (Stage I with separate U-Nets for ZeroGPU)
076b9c5 verified
Raw History Blame Contribute Delete
2 kB
"""Image <-> tensor conversion used everywhere, so that every script feeds the models the same values.
Images are 1 x 3 x H x W float tensors in [0, 1]; Stage I works in [-1, 1] (to_signed / to_unit_range). Conversion
matches torchvision's to_tensor / to_pil_image: division by 255, and quantisation by truncation."""
import numpy as np
import torch
from PIL import Image
def image_to_tensor(image, multiple=1):
"""PIL image (or HxWx3 uint8 array) -> 1x3xHxW float in [0, 1] on the CPU, cropped (bottom/right) to a multiple."""
arr = np.asarray(image.convert("RGB") if isinstance(image, Image.Image) else image)
h, w = arr.shape[0] - arr.shape[0] % multiple, arr.shape[1] - arr.shape[1] % multiple
return torch.from_numpy(np.array(arr[:h, :w])).permute(2, 0, 1).contiguous().float().div(255)[None]
def read_image(path, device="cpu", multiple=1):
return image_to_tensor(Image.open(path), multiple).to(device)
def tensor_to_uint8(x):
"""1x3xHxW float in [0, 1] -> HxWx3 uint8, quantised by truncation (quantised on the tensor's device)."""
return (x[0].float().clamp(0, 1) * 255.0).to(torch.uint8).permute(1, 2, 0).cpu().numpy()
def save_image(x, path, compress_level=1):
"""Lossless PNG of a 1x3xHxW float tensor in [0, 1]; a low zlib level keeps writing fast."""
Image.fromarray(tensor_to_uint8(x)).save(path, compress_level=compress_level)
def to_signed(x):
"""[0, 1] -> [-1, 1] (Stage I input range)."""
return x * 2 - 1
def to_unit_range(y):
"""[-1, 1] -> [0, 1] in float32, not clamped."""
return y.float() * 0.5 + 0.5
def resize_to_multiple(image, long_side, multiple=16):
"""PIL image with its long side at most `long_side` and both sides multiples of `multiple` (LANCZOS)."""
s = min(1.0, long_side / max(image.size))
w = max(multiple, int(image.width * s) // multiple * multiple)
h = max(multiple, int(image.height * s) // multiple * multiple)
return image.convert("RGB").resize((w, h), Image.LANCZOS)