def __call__(self, x: sitk.Image) -> sitk.Image: """Apply the transform. Parameters ---------- image Image to transform. Returns ------- sitk.Image The transformed image. """ angle = -self.max_angle + 2 * self.max_angle * torch.rand(1).item() rotation_centre = np.array(x.GetSize()) / 2 rotation_centre = x.TransformContinuousIndexToPhysicalPoint( rotation_centre) rotation = sitk.Euler3DTransform( rotation_centre, 0, # the angle of rotation around the x-axis, in radians -> coronal rotation 0, # the angle of rotation around the y-axis, in radians -> saggittal rotation angle, # the angle of rotation around the z-axis, in radians -> axial rotation (0., 0., 0.) # no translation ) return sitk.Resample(x, x, rotation, sitk.sitkLinear, self.fill_value)
def zoom(image: sitk.Image, scale_factor: Union[float, Sequence[float]], interpolation: str = "linear", anti_alias: bool = True, anti_alias_sigma: Optional[float] = None) -> sitk.Image: """Rescale image, preserving its spatial extent. The rescaled image will have the same spatial extent (size) but will be rescaled by `scale_factor` in each dimension. Alternatively, a separate scale factor for each dimension can be specified by passing a sequence of floats. Parameters ---------- image The image to rescale. scale_factor If float, each dimension will be scaled by that factor. If tuple, each dimension will be scaled by the corresponding element. interpolation, optional The interpolation method to use. Valid options are: - "linear" for bi/trilinear interpolation (default) - "nearest" for nearest neighbour interpolation - "bspline" for order-3 b-spline interpolation anti_alias, optional Whether to smooth the image with a Gaussian kernel before resampling. Only used when downsampling, i.e. when `size < image.GetSize()`. This should be used to avoid aliasing artifacts. anti_alias_sigma, optional The standard deviation of the Gaussian kernel used for anti-aliasing. Returns ------- sitk.Image The rescaled image. """ dimension = image.GetDimension() if isinstance(scale_factor, float): scale_factor = (scale_factor, ) * dimension centre_idx = np.array(image.GetSize()) / 2 centre = image.TransformContinuousIndexToPhysicalPoint(centre_idx) transform = sitk.ScaleTransform(dimension, scale_factor) transform.SetCenter(centre) return resample(image, spacing=image.GetSpacing(), interpolation=interpolation, anti_alias=anti_alias, anti_alias_sigma=anti_alias_sigma, transform=transform, output_size=image.GetSize())
def _serialize_candidates( *, candidates: Iterable[Tuple[float, ...]], candidate_scores: List[Any], ref_image: SimpleITK.Image, ) -> List[Dict]: data = [] for coord, score in zip(candidates, candidate_scores): world_coords = ref_image.TransformContinuousIndexToPhysicalPoint( [c for c in reversed(coord)]) coord_data = { f"coord{k}": v for k, v in zip(["X", "Y", "Z"], world_coords) } coord_data.update({"score": score}) data.append(coord_data) return data
def get_reference_image( image: sitk.Image, spacing: TypeTripletFloat, ) -> sitk.Image: old_spacing = np.array(image.GetSpacing()) new_spacing = np.array(spacing) old_size = np.array(image.GetSize()) new_size = old_size * old_spacing / new_spacing new_size = np.ceil(new_size).astype(np.uint16) new_size[old_size == 1] = 1 # keep singleton dimensions new_origin_index = 0.5 * (new_spacing / old_spacing - 1) new_origin_lps = image.TransformContinuousIndexToPhysicalPoint( new_origin_index) reference = sitk.Image(*new_size.tolist(), sitk.sitkFloat32) reference.SetDirection(image.GetDirection()) reference.SetSpacing(new_spacing.tolist()) reference.SetOrigin(new_origin_lps) return reference
def get_rigid_transforms( self, degrees_params: np.ndarray, translation_params: np.ndarray, image: sitk.Image, ) -> List[sitk.Euler3DTransform]: center_ijk = np.array(image.GetSize()) / 2 center_lps = image.TransformContinuousIndexToPhysicalPoint(center_ijk) identity = np.eye(4) matrices = [identity] for degrees, translation in zip(degrees_params, translation_params): radians = np.radians(degrees).tolist() motion = sitk.Euler3DTransform() motion.SetCenter(center_lps) motion.SetRotation(*radians) motion.SetTranslation(translation.tolist()) motion_matrix = self.transform_to_matrix(motion) matrices.append(motion_matrix) transforms = [self.matrix_to_transform(m) for m in matrices] return transforms
def get_reference_image( floating_sitk: sitk.Image, spacing: TypeTripletFloat, ) -> sitk.Image: old_spacing = np.array(floating_sitk.GetSpacing()) new_spacing = np.array(spacing) old_size = np.array(floating_sitk.GetSize()) new_size = old_size * old_spacing / new_spacing new_size = np.ceil(new_size).astype(np.uint16) new_size[old_size == 1] = 1 # keep singleton dimensions new_origin_index = 0.5 * (new_spacing / old_spacing - 1) new_origin_lps = floating_sitk.TransformContinuousIndexToPhysicalPoint( new_origin_index) reference = sitk.Image( new_size.tolist(), floating_sitk.GetPixelID(), floating_sitk.GetNumberOfComponentsPerPixel(), ) reference.SetDirection(floating_sitk.GetDirection()) reference.SetSpacing(new_spacing.tolist()) reference.SetOrigin(new_origin_lps) return reference