Пример #1
0
    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
Пример #2
0
 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)
Пример #3
0
 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)
Пример #4
0
 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)
Пример #5
0
    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)
Пример #6
0
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