image-deblurring / src /rstor /synthetic_data /dead_leaves_sampler.py
balthou's picture
initiate demo
cec5823
from typing import Tuple, Optional, List
from rstor.properties import SAMPLER_SATURATED, SAMPLER_NATURAL, SAMPLER_UNIFORM
from rstor.synthetic_data.color_sampler import sample_uniform_rgb, sample_saturated_color, sample_color_from_images
import numpy as np
from pathlib import Path
def define_dead_leaves_chart(
size: Tuple[int, int] = (100, 100),
number_of_circles: int = -1,
colored: Optional[bool] = True,
radius_min: Optional[int] = -1,
radius_max: Optional[int] = -1,
radius_alpha: Optional[int] = 3,
seed: int = None,
sampler=SAMPLER_UNIFORM,
natural_image_list: Optional[List[Path]] = None
) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]:
"""
Defines the geometric and color properties of the primitives in the dead leaves chart to later be sampled.
Args:
size (Tuple[int, int], optional): size of the generated chart. Defaults to (100, 100).
number_of_circles (int, optional): number of circles to generate.
If negative, it is computed based on the size. Defaults to -1.
colored (Optional[bool], optional): Whether to generate colored circles. Defaults to True.
radius_min (Optional[int], optional): minimum radius of the circles. Defaults to -1. (=> 1)
radius_max (Optional[int], optional): maximum radius of the circles. Defaults to -1. (=> 2000)
radius_alpha (Optional[int], optional): standard deviation of the radius of the circles.
If negative, it is calculated based on the size. Defaults to -1.
seed (int, optional): seed for the random number generator. Defaults to None
Returns:
Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]: center_x, center_y, radius, color
"""
rng = np.random.default_rng(np.random.SeedSequence(seed))
if number_of_circles < 0:
number_of_circles = 30 * max(size)
if radius_min < 0.:
radius_min = 1.
if radius_max < 0.:
radius_max = 2000.
# Pick random circle centers and radii
center_x = rng.integers(0, size[1], size=number_of_circles)
center_y = rng.integers(0, size[0], size=number_of_circles)
# Sample from a power law distribution for the p(radius=r) = (r.clip(radius_min, radius_max))^(-alpha)
radius = rng.uniform(
low=radius_max ** (1 - radius_alpha),
high=radius_min ** (1 - radius_alpha),
size=number_of_circles
)
# Using the change of variables formula for random variables.
radius = radius ** (-1/(radius_alpha - 1))
radius = radius.round().astype(int)
# Pick random colors
if colored:
if sampler == SAMPLER_UNIFORM:
color = sample_uniform_rgb(number_of_circles, seed=rng.integers(0, 1e10)).astype(float)
elif sampler == SAMPLER_SATURATED:
color = sample_saturated_color(number_of_circles, seed=rng.integers(0, 1e10)).astype(float)
elif sampler == SAMPLER_NATURAL:
assert natural_image_list is not None, "Please provide a list of images to sample colors from."
color = sample_color_from_images(number_of_circles, seed=rng.integers(0, 1e10),
path_to_images=natural_image_list).astype(float)
else:
raise NotImplementedError(f"Unknown color sampler {sampler}")
else:
color = rng.uniform(0.25, 0.75, size=(number_of_circles, 1))
return center_x, center_y, radius, color