def resample_and_clip( cls, data_array: NdarrayOrTensor, output_spatial_shape: Optional[Sequence[int]] = None, mode: str = InterpolateMode.BICUBIC, ): """ Resample ``data_array`` to ``output_spatial_shape`` if needed. Args: data_array: input data array. This method assumes the 'channel-last' format. output_spatial_shape: output spatial shape. mode: interpolation mode, defautl is ``InterpolateMode.BICUBIC``. """ data: np.ndarray = convert_data_type(data_array, np.ndarray)[0] if output_spatial_shape is not None: output_spatial_shape_ = ensure_tuple_rep(output_spatial_shape, 2) mode = look_up_option(mode, InterpolateMode) align_corners = None if mode in (InterpolateMode.NEAREST, InterpolateMode.AREA) else False xform = Resize(spatial_size=output_spatial_shape_, mode=mode, align_corners=align_corners) _min, _max = np.min(data), np.max(data) if len(data.shape) == 3: data = np.moveaxis(data, -1, 0) # to channel first data = convert_data_type(xform(data), np.ndarray)[0] # type: ignore data = np.moveaxis(data, 0, -1) else: # (H, W) data = np.expand_dims(data, 0) # make a channel data = convert_data_type(xform(data), np.ndarray)[0][0] # type: ignore if mode != InterpolateMode.NEAREST: data = np.clip(data, _min, _max) return data
def __init__(self, keys: KeysCollection, spatial_size, interp_order: str = "area", align_corners: Optional[bool] = None): super().__init__(keys) self.interp_order = ensure_tuple_rep(interp_order, len(self.keys)) self.resizer = Resize(spatial_size=spatial_size, align_corners=align_corners)
def __init__( self, keys: KeysCollection, spatial_size: Union[Sequence[int], int], mode: InterpolateModeSequence = InterpolateMode.AREA, align_corners: Union[Sequence[Optional[bool]], Optional[bool]] = None, ) -> None: super().__init__(keys) self.mode = ensure_tuple_rep(mode, len(self.keys)) self.align_corners = ensure_tuple_rep(align_corners, len(self.keys)) self.resizer = Resize(spatial_size=spatial_size)
def __init__(self, keys, spatial_size, order=1, mode='reflect', cval=0, clip=True, preserve_range=True, anti_aliasing=True, anti_aliasing_sigma=None): super().__init__(keys) self.resizer = Resize(spatial_size, order, mode, cval, clip, preserve_range, anti_aliasing, anti_aliasing_sigma)
def __init__( self, keys, spatial_size, order=1, mode="reflect", cval=0, clip=True, preserve_range=True, anti_aliasing=True, ): super().__init__(keys) self.order = ensure_tuple_rep(order, len(self.keys)) self.mode = ensure_tuple_rep(mode, len(self.keys)) self.cval = ensure_tuple_rep(cval, len(self.keys)) self.clip = ensure_tuple_rep(clip, len(self.keys)) self.preserve_range = ensure_tuple_rep(preserve_range, len(self.keys)) self.anti_aliasing = ensure_tuple_rep(anti_aliasing, len(self.keys)) self.resizer = Resize(spatial_size=spatial_size)
def write_png( data: np.ndarray, file_name: str, output_spatial_shape: Optional[Sequence[int]] = None, mode: Union[InterpolateMode, str] = InterpolateMode.BICUBIC, scale: Optional[int] = None, ) -> None: """ Write numpy data into png files to disk. Spatially it supports HW for 2D.(H,W) or (H,W,3) or (H,W,4). If `scale` is None, expect the input data in `np.uint8` or `np.uint16` type. It's based on the Image module in PIL library: https://pillow.readthedocs.io/en/stable/reference/Image.html Args: data: input data to write to file. file_name: expected file name that saved on disk. output_spatial_shape: spatial shape of the output image. mode: {``"nearest"``, ``"linear"``, ``"bilinear"``, ``"bicubic"``, ``"trilinear"``, ``"area"``} The interpolation mode. Defaults to ``"bicubic"``. See also: https://pytorch.org/docs/stable/nn.functional.html#interpolate scale: {``255``, ``65535``} postprocess data by clipping to [0, 1] and scaling to [0, 255] (uint8) or [0, 65535] (uint16). Default is None to disable scaling. Raises: ValueError: When ``scale`` is not one of [255, 65535]. """ if not isinstance(data, np.ndarray): raise ValueError("input data must be numpy array.") if len( data.shape ) == 3 and data.shape[2] == 1: # PIL Image can't save image with 1 channel data = data.squeeze(2) if output_spatial_shape is not None: output_spatial_shape_ = ensure_tuple_rep(output_spatial_shape, 2) mode = look_up_option(mode, InterpolateMode) align_corners = None if mode in (InterpolateMode.NEAREST, InterpolateMode.AREA) else False xform = Resize(spatial_size=output_spatial_shape_, mode=mode, align_corners=align_corners) _min, _max = np.min(data), np.max(data) if len(data.shape) == 3: data = np.moveaxis(data, -1, 0) # to channel first data = xform(data) # type: ignore data = np.moveaxis(data, 0, -1) else: # (H, W) data = np.expand_dims(data, 0) # make a channel data = xform(data)[0] # type: ignore if mode != InterpolateMode.NEAREST: data = np.clip(data, _min, _max) # type: ignore if scale is not None: data = np.clip( data, 0.0, 1.0 ) # type: ignore # png writer only can scale data in range [0, 1] if scale == np.iinfo(np.uint8).max: data = (scale * data).astype(np.uint8) elif scale == np.iinfo(np.uint16).max: data = (scale * data).astype(np.uint16) else: raise ValueError( f"Unsupported scale: {scale}, available options are [255, 65535]" ) # PNG data must be int number if data.dtype not in (np.uint8, np.uint16): # type: ignore data = data.astype(np.uint8) data = np.moveaxis(data, 0, 1) img = Image.fromarray(data) img.save(file_name, "PNG") return