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)