Return a noisy 2D image with `num_objs` circles and a 2D mask image. The maximum and minimum radii of the circles are given as `rad_max` and `rad_min`. The mask will have `num_seg_classes` number of classes for segmentations labeled sequentially from 1, plus a background class represent
(
height: int,
width: int,
num_objs: int = 12,
rad_max: int = 30,
rad_min: int = 5,
noise_max: float = 0.0,
num_seg_classes: int = 5,
channel_dim: int | None = None,
random_state: np.random.RandomState | None = None,
)
| 19 | |
| 20 | |
| 21 | def create_test_image_2d( |
| 22 | height: int, |
| 23 | width: int, |
| 24 | num_objs: int = 12, |
| 25 | rad_max: int = 30, |
| 26 | rad_min: int = 5, |
| 27 | noise_max: float = 0.0, |
| 28 | num_seg_classes: int = 5, |
| 29 | channel_dim: int | None = None, |
| 30 | random_state: np.random.RandomState | None = None, |
| 31 | ) -> tuple[np.ndarray, np.ndarray]: |
| 32 | """ |
| 33 | Return a noisy 2D image with `num_objs` circles and a 2D mask image. The maximum and minimum radii of the circles |
| 34 | are given as `rad_max` and `rad_min`. The mask will have `num_seg_classes` number of classes for segmentations labeled |
| 35 | sequentially from 1, plus a background class represented as 0. If `noise_max` is greater than 0 then noise will be |
| 36 | added to the image taken from the uniform distribution on range `[0,noise_max)`. If `channel_dim` is None, will create |
| 37 | an image without channel dimension, otherwise create an image with channel dimension as first dim or last dim. |
| 38 | |
| 39 | Args: |
| 40 | height: height of the image. The value should be larger than `2 * rad_max`. |
| 41 | width: width of the image. The value should be larger than `2 * rad_max`. |
| 42 | num_objs: number of circles to generate. Defaults to `12`. |
| 43 | rad_max: maximum circle radius. Defaults to `30`. |
| 44 | rad_min: minimum circle radius. Defaults to `5`. |
| 45 | noise_max: if greater than 0 then noise will be added to the image taken from |
| 46 | the uniform distribution on range `[0,noise_max)`. Defaults to `0`. |
| 47 | num_seg_classes: number of classes for segmentations. Defaults to `5`. |
| 48 | channel_dim: if None, create an image without channel dimension, otherwise create |
| 49 | an image with channel dimension as first dim or last dim. Defaults to `None`. |
| 50 | random_state: the random generator to use. Defaults to `np.random`. |
| 51 | |
| 52 | Returns: |
| 53 | Randomised Numpy array with shape (`height`, `width`) |
| 54 | """ |
| 55 | |
| 56 | if rad_max <= rad_min: |
| 57 | raise ValueError(f"`rad_min` {rad_min} should be less than `rad_max` {rad_max}.") |
| 58 | if rad_min < 1: |
| 59 | raise ValueError(f"`rad_min` {rad_min} should be no less than 1.") |
| 60 | min_size = min(height, width) |
| 61 | if min_size <= 2 * rad_max: |
| 62 | raise ValueError(f"the minimal size {min_size} of the image should be larger than `2 * rad_max` 2x{rad_max}.") |
| 63 | |
| 64 | image = np.zeros((height, width)) |
| 65 | rs: np.random.RandomState = np.random.random.__self__ if random_state is None else random_state # type: ignore |
| 66 | |
| 67 | for _ in range(num_objs): |
| 68 | x = rs.randint(rad_max, height - rad_max) |
| 69 | y = rs.randint(rad_max, width - rad_max) |
| 70 | rad = rs.randint(rad_min, rad_max) |
| 71 | spy, spx = np.ogrid[-x : height - x, -y : width - y] |
| 72 | circle = (spx * spx + spy * spy) <= rad * rad |
| 73 | |
| 74 | if num_seg_classes > 1: |
| 75 | image[circle] = np.ceil(rs.random() * num_seg_classes) |
| 76 | else: |
| 77 | image[circle] = rs.random() * 0.5 + 0.5 |
| 78 |
searching dependent graphs…