Spaces:
Runtime error
Runtime error
File size: 4,060 Bytes
fb0ea94 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
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
|