Functional implementation of zoom. This function operates eagerly or lazily according to ``lazy`` (default ``False``). Args: img: data to be changed, assuming `img` is channel-first. scale_factor: The zoom factor along the spatial axes. If a float, zoom
(img, scale_factor, keep_size, mode, padding_mode, align_corners, dtype, lazy, transform_info, **kwargs)
| 454 | |
| 455 | |
| 456 | def zoom(img, scale_factor, keep_size, mode, padding_mode, align_corners, dtype, lazy, transform_info, **kwargs): |
| 457 | """ |
| 458 | Functional implementation of zoom. |
| 459 | This function operates eagerly or lazily according to |
| 460 | ``lazy`` (default ``False``). |
| 461 | |
| 462 | Args: |
| 463 | img: data to be changed, assuming `img` is channel-first. |
| 464 | scale_factor: The zoom factor along the spatial axes. |
| 465 | If a float, zoom is the same for each spatial axis. |
| 466 | If a sequence, zoom should contain one value for each spatial axis. |
| 467 | keep_size: Whether keep original size (padding/slicing if needed). |
| 468 | mode: {``"bilinear"``, ``"nearest"``} |
| 469 | Interpolation mode to calculate output values. |
| 470 | See also: https://pytorch.org/docs/stable/generated/torch.nn.functional.grid_sample.html |
| 471 | padding_mode: {``"zeros"``, ``"border"``, ``"reflection"``} |
| 472 | Padding mode for outside grid values. |
| 473 | See also: https://pytorch.org/docs/stable/generated/torch.nn.functional.grid_sample.html |
| 474 | align_corners: See also: https://pytorch.org/docs/stable/generated/torch.nn.functional.grid_sample.html |
| 475 | dtype: data type for resampling computation. |
| 476 | If None, use the data type of input data. To be compatible with other modules, |
| 477 | the output data type is always ``float32``. |
| 478 | lazy: a flag that indicates whether the operation should be performed lazily or not |
| 479 | transform_info: a dictionary with the relevant information pertaining to an applied transform. |
| 480 | |
| 481 | """ |
| 482 | im_shape = img.peek_pending_shape() if isinstance(img, MetaTensor) else img.shape[1:] |
| 483 | output_size = [int(math.floor(float(i) * z)) for i, z in zip(im_shape, scale_factor)] |
| 484 | xform = scale_affine(im_shape, output_size, align_corners=align_corners if align_corners is not None else False) |
| 485 | extra_info = { |
| 486 | "mode": mode, |
| 487 | "align_corners": align_corners if align_corners is not None else TraceKeys.NONE, |
| 488 | "dtype": str(dtype)[6:], # dtype as string; remove "torch": torch.float32 -> float32 |
| 489 | "do_padcrop": False, |
| 490 | "padcrop": {}, |
| 491 | } |
| 492 | if keep_size: |
| 493 | do_pad_crop = not np.allclose(output_size, im_shape) |
| 494 | if do_pad_crop and lazy: # update for lazy evaluation |
| 495 | _pad_crop = ResizeWithPadOrCrop(spatial_size=im_shape, mode=padding_mode, **kwargs) |
| 496 | _pad_crop.lazy = True |
| 497 | _tmp_img = MetaTensor([], affine=torch.eye(len(output_size) + 1)) |
| 498 | _tmp_img.push_pending_operation({LazyAttr.SHAPE: list(output_size), LazyAttr.AFFINE: xform}) |
| 499 | lazy_cropped = _pad_crop(_tmp_img) |
| 500 | if isinstance(lazy_cropped, MetaTensor): |
| 501 | xform = lazy_cropped.peek_pending_affine() |
| 502 | extra_info["padcrop"] = lazy_cropped.pending_operations[-1] |
| 503 | extra_info["do_padcrop"] = do_pad_crop |
| 504 | output_size = [int(i) for i in im_shape] |
| 505 | meta_info = TraceableTransform.track_transform_meta( |
| 506 | img, |
| 507 | sp_size=output_size, |
| 508 | affine=xform, |
| 509 | extra_info=extra_info, |
| 510 | orig_size=im_shape, |
| 511 | transform_info=transform_info, |
| 512 | lazy=lazy, |
| 513 | ) |
no test coverage detected
searching dependent graphs…