Compute the crop slices based on specified `center & size` or `start & end` or `slices`. Args: roi_center: voxel coordinates for center of the crop ROI. roi_size: size of the crop ROI, if a dimension of ROI size is larger than image size, wil
(
roi_center: Sequence[int] | int | NdarrayOrTensor | None = None,
roi_size: Sequence[int] | int | NdarrayOrTensor | None = None,
roi_start: Sequence[int] | int | NdarrayOrTensor | None = None,
roi_end: Sequence[int] | int | NdarrayOrTensor | None = None,
roi_slices: Sequence[slice] | None = None,
)
| 360 | |
| 361 | @staticmethod |
| 362 | def compute_slices( |
| 363 | roi_center: Sequence[int] | int | NdarrayOrTensor | None = None, |
| 364 | roi_size: Sequence[int] | int | NdarrayOrTensor | None = None, |
| 365 | roi_start: Sequence[int] | int | NdarrayOrTensor | None = None, |
| 366 | roi_end: Sequence[int] | int | NdarrayOrTensor | None = None, |
| 367 | roi_slices: Sequence[slice] | None = None, |
| 368 | ) -> tuple[slice]: |
| 369 | """ |
| 370 | Compute the crop slices based on specified `center & size` or `start & end` or `slices`. |
| 371 | |
| 372 | Args: |
| 373 | roi_center: voxel coordinates for center of the crop ROI. |
| 374 | roi_size: size of the crop ROI, if a dimension of ROI size is larger than image size, |
| 375 | will not crop that dimension of the image. |
| 376 | roi_start: voxel coordinates for start of the crop ROI. |
| 377 | roi_end: voxel coordinates for end of the crop ROI, if a coordinate is out of image, |
| 378 | use the end coordinate of image. |
| 379 | roi_slices: list of slices for each of the spatial dimensions. |
| 380 | |
| 381 | """ |
| 382 | roi_start_t: torch.Tensor |
| 383 | |
| 384 | if roi_slices: |
| 385 | if not all(s.step is None or s.step == 1 for s in roi_slices): |
| 386 | raise ValueError(f"only slice steps of 1/None are currently supported, got {roi_slices}.") |
| 387 | return ensure_tuple(roi_slices) |
| 388 | else: |
| 389 | if roi_center is not None and roi_size is not None: |
| 390 | roi_center_t = convert_to_tensor(data=roi_center, dtype=torch.int16, wrap_sequence=True, device="cpu") |
| 391 | roi_size_t = convert_to_tensor(data=roi_size, dtype=torch.int16, wrap_sequence=True, device="cpu") |
| 392 | _zeros = torch.zeros_like(roi_center_t) |
| 393 | half = torch.divide(roi_size_t, 2, rounding_mode="floor") |
| 394 | roi_start_t = torch.maximum(roi_center_t - half, _zeros) |
| 395 | roi_end_t = torch.maximum(roi_start_t + roi_size_t, roi_start_t) |
| 396 | else: |
| 397 | if roi_start is None or roi_end is None: |
| 398 | raise ValueError("please specify either roi_center, roi_size or roi_start, roi_end.") |
| 399 | roi_start_t = convert_to_tensor(data=roi_start, dtype=torch.int16, wrap_sequence=True) |
| 400 | roi_start_t = torch.maximum(roi_start_t, torch.zeros_like(roi_start_t)) |
| 401 | roi_end_t = convert_to_tensor(data=roi_end, dtype=torch.int16, wrap_sequence=True) |
| 402 | roi_end_t = torch.maximum(roi_end_t, roi_start_t) |
| 403 | # convert to slices (accounting for 1d) |
| 404 | if roi_start_t.numel() == 1: |
| 405 | return ensure_tuple([slice(int(roi_start_t.item()), int(roi_end_t.item()))]) |
| 406 | return ensure_tuple([slice(int(s), int(e)) for s, e in zip(roi_start_t.tolist(), roi_end_t.tolist())]) |
| 407 | |
| 408 | def __call__( # type: ignore[override] |
| 409 | self, img: torch.Tensor, slices: tuple[slice, ...], lazy: bool | None = None |
no test coverage detected