Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Geometric transform implementations #7955

Draft
wants to merge 31 commits into
base: dev
Choose a base branch
from
Draft
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
00436d0
Add `kind` property in `MetaTensor` (#7488)
KumoLiu Apr 12, 2024
b2ab07e
Adding apply_to_geometry function
atbenmurray Jul 11, 2024
7c7ec30
Adding load_geometry function
atbenmurray Jul 11, 2024
8077759
Adding missing import for apply_to_geometry
atbenmurray Jul 11, 2024
7edb44e
Adding KindKeys to __all__ in monai.utils.enums.py
atbenmurray Jul 11, 2024
61cb5c3
Adding tests for apply_to_geometry
atbenmurray Jul 11, 2024
1e83ec8
Adding apply_to_geometry to __all__ in lazy/functional.py
atbenmurray Jul 11, 2024
e503d6a
Adding flip functionality for geometric_tensors
atbenmurray Jul 11, 2024
f345fc9
Adding KindKeys to utils/__init__
atbenmurray Jul 11, 2024
edc4bb7
Adding | None to meta_info for apply_to_geometry
atbenmurray Jul 11, 2024
b8baae9
Adding resize functionality for geometric tensors
atbenmurray Jul 11, 2024
e59b4a9
Adding rotate functionality for geometric tensors
atbenmurray Jul 11, 2024
a0b768e
Fixing line endings for monai/transforms/io/functional.py
atbenmurray Jul 11, 2024
4e6ae70
Fixed rotate to that output_shape is returned. Made resize consistent…
atbenmurray Jul 19, 2024
f763c8f
Work towards geometry tests for rotate
atbenmurray Jul 19, 2024
fc8e0b8
Fixed KindKey types for flip functionality
atbenmurray Jul 19, 2024
0857ac7
Fix to handle 2d data being multiplied by a 3d transform from the met…
atbenmurray Jul 26, 2024
aa83926
Bug fixes to make all related unit tests pass
atbenmurray Jul 26, 2024
55edf77
Removed ndims (not ndim) from MetaTensor
atbenmurray Jul 26, 2024
7928f32
Adding tests for rotate / flip
atbenmurray Jul 26, 2024
1a216e9
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 26, 2024
7004598
load_geometry functionality and tests
atbenmurray Aug 2, 2024
51d8d28
Resolving conflict
atbenmurray Aug 2, 2024
62f506b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 2, 2024
4740533
Adding spatial_dims_from_tensorlike function to handle point tensors
atbenmurray Aug 2, 2024
2ff1d73
Zoom modified to use spatial_dims_from_tensorlike
atbenmurray Aug 2, 2024
c2d351f
Merge branch 'geometric_all' of github.com:atbenmurray/monai into geo…
atbenmurray Aug 2, 2024
645e0c6
Added and tested point zoom functionality
atbenmurray Aug 2, 2024
f2e2426
Adding traced_no_op function for use in transforms that no-op geometr…
atbenmurray Aug 2, 2024
4898b88
Adding geometry support to Spacing transform
atbenmurray Aug 2, 2024
2cda79a
Adding save_geometry function plus test
atbenmurray Aug 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Adding apply_to_geometry function
Signed-off-by: Ben Murray <ben.murray@gmail.com>
atbenmurray committed Jul 11, 2024
commit b2ab07eab2b4603f56651c59aecd1ac3c2900c8c
51 changes: 50 additions & 1 deletion monai/transforms/lazy/functional.py
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@

from monai.apps.utils import get_logger
from monai.config import NdarrayOrTensor
from monai.data.meta_obj import MetaObj
from monai.data.meta_tensor import MetaTensor
from monai.data.utils import to_affine_nd
from monai.transforms.lazy.utils import (
@@ -28,7 +29,7 @@
)
from monai.transforms.traits import LazyTrait
from monai.transforms.transform import MapTransform
from monai.utils import LazyAttr, look_up_option
from monai.utils import LazyAttr, MetaKeys, convert_to_tensor, look_up_option

__all__ = ["apply_pending_transforms", "apply_pending_transforms_in_order", "apply_pending"]

@@ -293,3 +294,51 @@ def apply_pending(data: torch.Tensor | MetaTensor, pending: list | None = None,
for p in pending:
data.push_applied_operation(p)
return data, pending


def apply_to_geometry(
data: torch.Tensor,
meta_info: dict | MetaObj = None,
transform: torch.Tensor | None = None,
):
"""
Apply an affine geometric transform or deformation field to geometry.
At present this is limited to the transformation of points.

The points must be provided as a tensor and must be compatible with a homogeneous
transform. This means that:
- 2D points are of the form (x, y, 1)
- 3D points are of the form (x, y, z, 1)

The affine transform or deformation field is applied to the the points and a tensor of
the same shape as the input tensor is returned.

Args:
data: the tensor of points to be transformed.
meta_info: the metadata containing the affine transformation
"""

if meta_info is None and transform is None:
raise ValueError("either meta_info or transform must be provided")
if meta_info is not None and transform is not None:
raise ValueError("only one of meta_info or transform can be provided")

if not isinstance(data, (torch.Tensor, MetaTensor)):
raise TypeError(f"data {type(data)} must be a torch.Tensor or MetaTensor")

data = convert_to_tensor(data, track_meta=get_track_meta())

if meta_info is not None:
transform_ = meta_info.meta[MetaKeys.AFFINE]
else:
transform_ = transform

if transform_.dtype != data.dtype:
transform_ = transform_.to(data.dtype)

if data.shape[1] != transform_.shape[0]:
raise ValueError(f"second element of data.shape {data.shape} must match transform shape {transform_.shape}")

result = torch.matmul(data, transform_.T)

return result