|
24 | 24 | import monai |
25 | 25 | from monai.config import USE_COMPILED |
26 | 26 | from monai.config.type_definitions import NdarrayOrTensor |
| 27 | +from monai.data.box_utils import get_boxmode |
27 | 28 | from monai.data.meta_obj import get_track_meta |
28 | 29 | from monai.data.meta_tensor import MetaTensor |
29 | 30 | from monai.data.utils import AFFINE_TOL, compute_shape_offset, to_affine_nd |
|
32 | 33 | from monai.transforms.intensity.array import GaussianSmooth |
33 | 34 | from monai.transforms.inverse import TraceableTransform |
34 | 35 | from monai.transforms.utils import create_rotate, create_translate, resolves_modes, scale_affine |
35 | | -from monai.transforms.utils_pytorch_numpy_unification import allclose |
| 36 | +from monai.transforms.utils_pytorch_numpy_unification import allclose, concatenate, stack |
36 | 37 | from monai.utils import ( |
37 | 38 | LazyAttr, |
38 | 39 | TraceKeys, |
@@ -610,3 +611,71 @@ def affine_func( |
610 | 611 | out = _maybe_new_metatensor(img, dtype=torch.float32, device=resampler.device) |
611 | 612 | out = out.copy_meta_from(meta_info) if isinstance(out, MetaTensor) else out |
612 | 613 | return out if image_only else (out, affine) |
| 614 | + |
| 615 | + |
| 616 | +def convert_box_to_points(bbox, mode): |
| 617 | + """ |
| 618 | + Converts an axis-aligned bounding box to points. |
| 619 | +
|
| 620 | + Args: |
| 621 | + mode: The mode specifying how to interpret the bounding box. |
| 622 | + bbox: Bounding boxes of the shape (N, C) for N boxes. C is [x1, y1, x2, y2] for 2D or [x1, y1, z1, x2, y2, z2] |
| 623 | + for 3D for each box. Return shape will be (N, 4, 2) for 2D or (N, 8, 3) for 3D. |
| 624 | +
|
| 625 | + Returns: |
| 626 | + sequence of points representing the corners of the bounding box. |
| 627 | + """ |
| 628 | + |
| 629 | + mode = get_boxmode(mode) |
| 630 | + |
| 631 | + points_list = [] |
| 632 | + for _num in range(bbox.shape[0]): |
| 633 | + corners = mode.boxes_to_corners(bbox[_num : _num + 1]) |
| 634 | + if len(corners) == 4: |
| 635 | + points_list.append( |
| 636 | + concatenate( |
| 637 | + [ |
| 638 | + concatenate([corners[0], corners[1]], axis=1), |
| 639 | + concatenate([corners[2], corners[1]], axis=1), |
| 640 | + concatenate([corners[2], corners[3]], axis=1), |
| 641 | + concatenate([corners[0], corners[3]], axis=1), |
| 642 | + ], |
| 643 | + axis=0, |
| 644 | + ) |
| 645 | + ) |
| 646 | + else: |
| 647 | + points_list.append( |
| 648 | + concatenate( |
| 649 | + [ |
| 650 | + concatenate([corners[0], corners[1], corners[2]], axis=1), |
| 651 | + concatenate([corners[3], corners[1], corners[2]], axis=1), |
| 652 | + concatenate([corners[3], corners[4], corners[2]], axis=1), |
| 653 | + concatenate([corners[0], corners[4], corners[2]], axis=1), |
| 654 | + concatenate([corners[0], corners[1], corners[5]], axis=1), |
| 655 | + concatenate([corners[3], corners[1], corners[5]], axis=1), |
| 656 | + concatenate([corners[3], corners[4], corners[5]], axis=1), |
| 657 | + concatenate([corners[0], corners[4], corners[5]], axis=1), |
| 658 | + ], |
| 659 | + axis=0, |
| 660 | + ) |
| 661 | + ) |
| 662 | + |
| 663 | + return stack(points_list, dim=0) |
| 664 | + |
| 665 | + |
| 666 | +def convert_points_to_box(points): |
| 667 | + """ |
| 668 | + Converts points to an axis-aligned bounding box. |
| 669 | +
|
| 670 | + Args: |
| 671 | + points: Points representing the corners of the bounding box. Shape (N, 8, 3) for the 8 corners of |
| 672 | + a 3D cuboid or (N, 4, 2) for the 4 corners of a 2D rectangle. |
| 673 | + """ |
| 674 | + from monai.transforms.utils_pytorch_numpy_unification import max, min |
| 675 | + |
| 676 | + mins = min(points, dim=1) |
| 677 | + maxs = max(points, dim=1) |
| 678 | + # Concatenate the min and max values to get the bounding boxes |
| 679 | + bboxes = concatenate([mins, maxs], axis=1) |
| 680 | + |
| 681 | + return bboxes |
0 commit comments