Functional implementation of changing the input image's orientation into the specified based on `spatial_ornt`. This function operates eagerly or lazily according to ``lazy`` (default ``False``). Args: img: data to be changed, assuming `img` is channel-first. origin
(img, original_affine, spatial_ornt, lazy, transform_info)
| 227 | |
| 228 | |
| 229 | def orientation(img, original_affine, spatial_ornt, lazy, transform_info) -> torch.Tensor: |
| 230 | """ |
| 231 | Functional implementation of changing the input image's orientation into the specified based on `spatial_ornt`. |
| 232 | This function operates eagerly or lazily according to |
| 233 | ``lazy`` (default ``False``). |
| 234 | |
| 235 | Args: |
| 236 | img: data to be changed, assuming `img` is channel-first. |
| 237 | original_affine: original affine of the input image. |
| 238 | spatial_ornt: orientations of the spatial axes, |
| 239 | see also https://nipy.org/nibabel/reference/nibabel.orientations.html |
| 240 | lazy: a flag that indicates whether the operation should be performed lazily or not |
| 241 | transform_info: a dictionary with the relevant information pertaining to an applied transform. |
| 242 | """ |
| 243 | spatial_shape = img.peek_pending_shape() if isinstance(img, MetaTensor) else img.shape[1:] |
| 244 | xform = nib.orientations.inv_ornt_aff(spatial_ornt, spatial_shape) |
| 245 | img = convert_to_tensor(img, track_meta=get_track_meta()) |
| 246 | |
| 247 | spatial_ornt[:, 0] += 1 # skip channel dim |
| 248 | spatial_ornt = np.concatenate([np.array([[0, 1]]), spatial_ornt]) |
| 249 | axes = [ax for ax, flip in enumerate(spatial_ornt[:, 1]) if flip == -1] |
| 250 | full_transpose = np.arange(len(spatial_shape) + 1) # channel-first array |
| 251 | full_transpose[: len(spatial_ornt)] = np.argsort(spatial_ornt[:, 0]) |
| 252 | extra_info = {"original_affine": original_affine} |
| 253 | |
| 254 | shape_np = convert_to_numpy(spatial_shape, wrap_sequence=True) |
| 255 | shape_np = shape_np[[i - 1 for i in full_transpose if i > 0]] |
| 256 | meta_info = TraceableTransform.track_transform_meta( |
| 257 | img, |
| 258 | sp_size=shape_np, |
| 259 | affine=xform, |
| 260 | extra_info=extra_info, |
| 261 | orig_size=spatial_shape, |
| 262 | transform_info=transform_info, |
| 263 | lazy=lazy, |
| 264 | ) |
| 265 | out = _maybe_new_metatensor(img) |
| 266 | if lazy: |
| 267 | return out.copy_meta_from(meta_info) if isinstance(out, MetaTensor) else meta_info # type: ignore |
| 268 | if axes: |
| 269 | out = torch.flip(out, dims=axes) |
| 270 | if not np.all(full_transpose == np.arange(len(out.shape))): |
| 271 | out = out.permute(full_transpose.tolist()) |
| 272 | return out.copy_meta_from(meta_info) if isinstance(out, MetaTensor) else out # type: ignore |
| 273 | |
| 274 | |
| 275 | def flip(img, sp_axes, lazy, transform_info): |
no test coverage detected
searching dependent graphs…