Spaces:
Running
Running
| import numpy as np | |
| import SimpleITK as sitk | |
| channels = [ | |
| "background", | |
| "spleen", | |
| "right_kidney", | |
| "left_kidney", | |
| "gallbladder", | |
| "liver", | |
| "stomach", | |
| "pancreas", | |
| "right_adrenal_gland", | |
| "left_adrenal_gland", | |
| "left_lung", | |
| "right_lung", | |
| "heart", | |
| "aorta", | |
| "inferior_vena_cava", | |
| "portal_vein_and_splenic_vein", | |
| "left_iliac_artery", | |
| "right_iliac_artery", | |
| "left_iliac_vena", | |
| "right_iliac_vena", | |
| "esophagus", | |
| "small_bowel", | |
| "duodenum", | |
| "colon", | |
| "urinary_bladder", | |
| "spine", | |
| "sacrum", | |
| "left_hip", | |
| "right_hip", | |
| "left_femur", | |
| "right_femur", | |
| "left_autochthonous_muscle", | |
| "right_autochthonous_muscle", | |
| "left_iliopsoas_muscle", | |
| "right_iliopsoas_muscle", | |
| "left_gluteus_maximus", | |
| "right_gluteus_maximus", | |
| "left_gluteus_medius", | |
| "right_gluteus_medius", | |
| "left_gluteus_minimus", | |
| "right_gluteus_minimus", | |
| ] | |
| def make_isotropic(image, interpolator=sitk.sitkLinear, spacing=None): | |
| """ | |
| Many file formats (e.g. jpg, png,...) expect the pixels to be isotropic, same | |
| spacing for all axes. Saving non-isotropic data in these formats will result in | |
| distorted images. This function makes an image isotropic via resampling, if needed. | |
| Args: | |
| image (SimpleITK.Image): Input image. | |
| interpolator: By default the function uses a linear interpolator. For | |
| label images one should use the sitkNearestNeighbor interpolator | |
| so as not to introduce non-existant labels. | |
| spacing (float): Desired spacing. If none given then use the smallest spacing from | |
| the original image. | |
| Returns: | |
| SimpleITK.Image with isotropic spacing which occupies the same region in space as | |
| the input image. | |
| """ | |
| original_spacing = image.GetSpacing() | |
| # Image is already isotropic, just return a copy. | |
| if all(spc == original_spacing[0] for spc in original_spacing): | |
| return sitk.Image(image) | |
| # Make image isotropic via resampling. | |
| original_size = image.GetSize() | |
| if spacing is None: | |
| spacing = min(original_spacing) | |
| new_spacing = [spacing] * image.GetDimension() | |
| new_size = [int(round(osz * ospc / spacing)) for osz, ospc in zip(original_size, original_spacing)] | |
| return sitk.Resample( | |
| image, | |
| new_size, | |
| sitk.Transform(), | |
| interpolator, | |
| image.GetOrigin(), | |
| new_spacing, | |
| image.GetDirection(), | |
| 0, # default pixel value | |
| image.GetPixelID(), | |
| ) | |
| def label_mapper(seg): | |
| labels = [] | |
| for _class in np.unique(seg): | |
| if _class == 0: | |
| continue | |
| labels.append((seg == _class, channels[_class])) | |
| return labels | |
| def sitk2numpy(img, normalize=False): | |
| img = sitk.DICOMOrient(img, "LPS") | |
| # img = make_isotropic(img) | |
| img = sitk.GetArrayFromImage(img) | |
| if normalize: | |
| minval, maxval = np.min(img), np.max(img) | |
| img = ((img - minval) / (maxval - minval)).clip(0, 1) * 255 | |
| img = img.astype(np.uint8) | |
| return img | |
| def read_image(path, normalize=False): | |
| img = sitk.ReadImage(path) | |
| return sitk2numpy(img, normalize) | |
| def display(image, seg=None, _slice=50): | |
| # Image | |
| if image is None or (isinstance(image, list) and len(image) == 0): | |
| return None | |
| if isinstance(image, list): | |
| image = image[-1] | |
| x = int(_slice * (image.shape[0] / 100)) | |
| image = image[x, :, :] | |
| # Segmentation | |
| if seg is None or (isinstance(seg, list) and len(seg) == 0): | |
| seg = [] | |
| else: | |
| if isinstance(seg, list): | |
| seg = seg[-1] | |
| seg = label_mapper(seg[x, :, :]) | |
| return image, seg | |
| def read_and_display(path, image_state, seg_state): | |
| image_state.clear() | |
| seg_state.clear() | |
| if path is not None: | |
| image = read_image(path, normalize=True) | |
| image_state.append(image) | |
| return display(image), image_state, seg_state | |
| else: | |
| return None, image_state, seg_state | |