Esempio n. 1
0
def store_image_as_short_nifti(image: np.ndarray, header: ImageHeader,
                               file_name: PathOrString,
                               args: Optional[SegmentationModelBase]) -> Path:
    """
    Saves an image in nifti format as ubyte, and performs the following operations:
    1) transpose the image back into X,Y,Z from Z,Y,X
    2) perform linear scaling from config.output_range to window level range, or
    byte range (0,255) if norm_method is not CT Window and scale is True
    3) cast the image values to ubyte before saving

    :param image: 3D image in shape: Z x Y x X.
    :param header: ImageHeader
    :param file_name: The name of the file for this image.
    :param args: The model config.
    :return: the path to the saved image
    """
    if args is not None and args.norm_method == PhotometricNormalizationMethod.CtWindow:
        output_range = get_range_for_window_level(args.level, args.window)
        return store_as_nifti(image=image,
                              header=header,
                              file_name=file_name,
                              image_type=np.short,
                              scale=True,
                              input_range=args.output_range,
                              output_range=output_range)
    # All normalization apart from CT Window can't be easily undone. The image should be somewhere in the
    # range -1 to 1, scale up by a factor of 1000 so that we can use all of the np.short range.
    return store_as_nifti(image=image * 1000,
                          header=header,
                          file_name=file_name,
                          image_type=np.short)
def test_store_image_as_short_nifti(test_output_dirs: TestOutputDirectories,
                                    norm_method: PhotometricNormalizationMethod,
                                    image_range: Any,
                                    window_level: Any) -> None:
    window, level = window_level if window_level else (400, 0)

    image = np.random.random_sample((1, 2, 3))
    image_shape = image.shape

    args = SegmentationModelBase(norm_method=norm_method, window=window, level=level, should_validate=False)

    # Get integer values that are in the image range
    image1 = LinearTransform.transform(data=image, input_range=(0, 1), output_range=args.output_range)
    image = image1.astype(np.short)  # type: ignore
    header = ImageHeader(origin=(1, 1, 1), direction=(1, 0, 0, 0, 1, 0, 0, 0, 1), spacing=(1, 1, 1))
    nifti_name = test_output_dirs.create_file_or_folder_path(default_image_name)
    io_util.store_image_as_short_nifti(image, header, nifti_name, args)

    if norm_method == PhotometricNormalizationMethod.CtWindow:
        output_range = get_range_for_window_level(args.level, args.window)
        image = LinearTransform.transform(data=image, input_range=args.output_range, output_range=output_range)
        image = image.astype(np.short)
    else:
        image = image * 1000

    t = np.unique(image)
    assert_nifti_content(nifti_name, image_shape, header, list(t), np.short)