コード例 #1
0
def store_as_nifti(
        image: np.ndarray,
        header: ImageHeader,
        file_name: PathOrString,
        image_type: Union[str, type, np.dtype],
        scale: bool = False,
        input_range: Optional[Iterable[Union[int, float]]] = None,
        output_range: Optional[Iterable[Union[int, float]]] = None) -> Path:
    """
    Saves an image in nifti format (uploading to Azure also if an online Run), and performs the following operations:
    1) transpose the image back into X,Y,Z from Z,Y,X
    2) if scale is true, then performs a linear scaling to either the input/output range or
    byte range (0,255) as default.
    3) cast the image values to the given type before saving

    :param image: 3D image in shape: Z x Y x X.
    :param header: The image header
    :param file_name: The name of the file for this image.
    :param scale: Should perform linear scaling of the image, to desired output range or byte range by default.
    :param input_range: The input range the image belongs to.
    :param output_range: The output range to scale the image to.
    :param image_type: The type to save the image in.
    :return: the path to the saved image
    """
    if image.ndim != 3:
        raise Exception("Image must have 3 dimensions, found: {}".format(
            len(image.shape)))

    if image_type is None:
        raise Exception("You must specify a valid image type.")

    if scale and ((input_range is not None and output_range is None) or
                  (input_range is None and output_range is not None)):
        raise Exception(
            "You must provide both input and output ranges to apply custom linear scaling."
        )

    # rescale image for visualization in the app
    if scale:
        if input_range is not None and output_range is not None:
            # noinspection PyTypeChecker
            image = LinearTransform.transform(
                data=image,
                input_range=input_range,  # type: ignore
                output_range=tuple(output_range)  # type: ignore
            )
        else:
            image = (image + 1) * 255

    image = sitk.GetImageFromArray(image.astype(image_type))
    image.SetSpacing(sitk.VectorDouble(reverse_tuple_float3(
        header.spacing)))  # Spacing needs to be X Y Z
    image.SetOrigin(header.origin)
    image.SetDirection(header.direction)
    sitk.WriteImage(image, str(file_name))
    return Path(file_name)