[docs]classRandomFlip(RandomTransform,SpatialTransform):"""Reverse the order of elements in an image along the given axes. Args: axes: Index or tuple of indices of the spatial dimensions along which the image might be flipped. If they are integers, they must be in ``(0, 1, 2)``. Anatomical labels may also be used, such as ``'Left'``, ``'Right'``, ``'Anterior'``, ``'Posterior'``, ``'Inferior'``, ``'Superior'``, ``'Height'`` and ``'Width'``, ``'AP'`` (antero-posterior), ``'lr'`` (lateral), ``'w'`` (width) or ``'i'`` (inferior). Only the first letter of the string will be used. If the image is 2D, ``'Height'`` and ``'Width'`` may be used. flip_probability: Probability that the image will be flipped. This is computed on a per-axis basis. **kwargs: See :class:`~torchio.transforms.Transform` for additional keyword arguments. Example: >>> import torchio as tio >>> fpg = tio.datasets.FPG() >>> flip = tio.RandomFlip(axes=('LR',)) # flip along lateral axis only .. tip:: It is handy to specify the axes as anatomical labels when the image orientation is not known. """def__init__(self,axes:Union[int,Tuple[int,...]]=0,flip_probability:float=0.5,**kwargs,):super().__init__(**kwargs)self.axes=_parse_axes(axes)self.flip_probability=self.parse_probability(flip_probability)defapply_transform(self,subject:Subject)->Subject:potential_axes=_ensure_axes_indices(subject,self.axes)axes_to_flip_hot=self.get_params(self.flip_probability)foriinrange(3):ifinotinpotential_axes:axes_to_flip_hot[i]=False(axes,)=np.where(axes_to_flip_hot)axes=axes.tolist()ifnotaxes:returnsubjectarguments={'axes':axes}transform=Flip(**self.add_include_exclude(arguments))transformed=transform(subject)assertisinstance(transformed,Subject)returntransformed@staticmethoddefget_params(probability:float)->List[bool]:return(probability>torch.rand(3)).tolist()
classFlip(SpatialTransform):"""Reverse the order of elements in an image along the given axes. Args: axes: Index or tuple of indices of the spatial dimensions along which the image will be flipped. See :class:`~torchio.transforms.augmentation.spatial.random_flip.RandomFlip` for more information. **kwargs: See :class:`~torchio.transforms.Transform` for additional keyword arguments. .. tip:: It is handy to specify the axes as anatomical labels when the image orientation is not known. """def__init__(self,axes,**kwargs):super().__init__(**kwargs)self.axes=_parse_axes(axes)self.args_names=('axes',)defapply_transform(self,subject:Subject)->Subject:axes=_ensure_axes_indices(subject,self.axes)forimageinself.get_images(subject):_flip_image(image,axes)returnsubject@staticmethoddefis_invertible():returnTruedefinverse(self):returnselfdef_parse_axes(axes:Union[int,Tuple[int,...]]):axes_tuple=to_tuple(axes)foraxisinaxes_tuple:is_int=isinstance(axis,int)is_string=isinstance(axis,str)valid_number=is_intandaxisin(0,1,2)ifnotis_stringandnotvalid_number:message=(f'All axes must be 0, 1 or 2, but found "{axis}" with type {type(axis)}')raiseValueError(message)returnaxes_tupledef_ensure_axes_indices(subject,axes):ifany(isinstance(n,str)forninaxes):subject.check_consistent_orientation()image=subject.get_first_image()axes=sorted(3+image.axis_name_to_index(n)forninaxes)returnaxesdef_flip_image(image,axes):spatial_axes=np.array(axes,int)+1data=image.numpy()data=np.flip(data,axis=spatial_axes)data=data.copy()# remove negative stridesdata=torch.as_tensor(data)image.set_data(data)