Functional implementation of rotate90. This function operates eagerly or lazily according to ``lazy`` (default ``False``). Args: img: data to be changed, assuming `img` is channel-first. axes: 2 int numbers, defines the plane to rotate with 2 spatial axes.
(img, axes, k, lazy, transform_info)
| 538 | |
| 539 | |
| 540 | def rotate90(img, axes, k, lazy, transform_info): |
| 541 | """ |
| 542 | Functional implementation of rotate90. |
| 543 | This function operates eagerly or lazily according to |
| 544 | ``lazy`` (default ``False``). |
| 545 | |
| 546 | Args: |
| 547 | img: data to be changed, assuming `img` is channel-first. |
| 548 | axes: 2 int numbers, defines the plane to rotate with 2 spatial axes. |
| 549 | If axis is negative it counts from the last to the first axis. |
| 550 | k: number of times to rotate by 90 degrees. |
| 551 | lazy: a flag that indicates whether the operation should be performed lazily or not |
| 552 | transform_info: a dictionary with the relevant information pertaining to an applied transform. |
| 553 | """ |
| 554 | extra_info = {"axes": [d - 1 for d in axes], "k": k} |
| 555 | ori_shape = img.peek_pending_shape() if isinstance(img, MetaTensor) else img.shape[1:] |
| 556 | sp_shape = list(ori_shape) |
| 557 | if k in (1, 3): |
| 558 | a_0, a_1 = axes[0] - 1, axes[1] - 1 |
| 559 | sp_shape[a_0], sp_shape[a_1] = ori_shape[a_1], ori_shape[a_0] |
| 560 | rank = img.peek_pending_rank() if isinstance(img, MetaTensor) else torch.tensor(3.0, dtype=torch.double) |
| 561 | r, sp_r = int(rank), len(ori_shape) |
| 562 | xform = to_affine_nd(r, create_translate(sp_r, [-float(d - 1) / 2 for d in sp_shape])) |
| 563 | s = -1.0 if int(axes[0]) - int(axes[1]) in (-1, 2) else 1.0 |
| 564 | if sp_r == 2: |
| 565 | rot90 = to_affine_nd(r, create_rotate(sp_r, [s * np.pi / 2])) |
| 566 | else: |
| 567 | idx = {1, 2, 3} - set(axes) |
| 568 | angle: list[float] = [0, 0, 0] |
| 569 | angle[idx.pop() - 1] = s * np.pi / 2 |
| 570 | rot90 = to_affine_nd(r, create_rotate(sp_r, angle)) |
| 571 | for _ in range(k): |
| 572 | xform = rot90 @ xform |
| 573 | xform = to_affine_nd(r, create_translate(sp_r, [float(d - 1) / 2 for d in ori_shape])) @ xform |
| 574 | meta_info = TraceableTransform.track_transform_meta( |
| 575 | img, |
| 576 | sp_size=sp_shape, |
| 577 | affine=xform, |
| 578 | extra_info=extra_info, |
| 579 | orig_size=ori_shape, |
| 580 | transform_info=transform_info, |
| 581 | lazy=lazy, |
| 582 | ) |
| 583 | out = _maybe_new_metatensor(img) |
| 584 | if lazy: |
| 585 | return out.copy_meta_from(meta_info) if isinstance(out, MetaTensor) else meta_info |
| 586 | out = torch.rot90(out, k, axes) |
| 587 | return out.copy_meta_from(meta_info) if isinstance(out, MetaTensor) else out |
| 588 | |
| 589 | |
| 590 | def affine_func( |
no test coverage detected
searching dependent graphs…