From 5973abcbda91f98bce28100188d8dada012ebe2a Mon Sep 17 00:00:00 2001 From: Andres Date: Tue, 29 Aug 2023 19:07:47 +0100 Subject: [PATCH 1/7] Add transform to apply orientation to guidance Signed-off-by: Andres --- sample-apps/radiology/lib/infers/deepedit.py | 2 + .../radiology/lib/transforms/transforms.py | 37 +++++++++++++++++++ sample-apps/radiology/main.py | 4 +- 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/sample-apps/radiology/lib/infers/deepedit.py b/sample-apps/radiology/lib/infers/deepedit.py index 152d1c45c..1285081ac 100644 --- a/sample-apps/radiology/lib/infers/deepedit.py +++ b/sample-apps/radiology/lib/infers/deepedit.py @@ -34,6 +34,7 @@ from monailabel.interfaces.tasks.infer_v2 import InferType from monailabel.tasks.infer.basic_infer import BasicInferTask from monailabel.transform.post import Restored +from lib.transforms.transforms import OrientationGuidanceMultipleLabelDeepEditd class DeepEdit(BasicInferTask): @@ -86,6 +87,7 @@ def pre_transforms(self, data=None): if self.type == InferType.DEEPEDIT: t.extend( [ + OrientationGuidanceMultipleLabelDeepEditd(key_click='click_coordinates', label_names=self.labels), AddGuidanceFromPointsDeepEditd(ref_image="image", guidance="guidance", label_names=self.labels), Resized(keys="image", spatial_size=self.spatial_size, mode="area"), ResizeGuidanceMultipleLabelDeepEditd(guidance="guidance", ref_image="image"), diff --git a/sample-apps/radiology/lib/transforms/transforms.py b/sample-apps/radiology/lib/transforms/transforms.py index bc0e6719a..3c829dc4d 100644 --- a/sample-apps/radiology/lib/transforms/transforms.py +++ b/sample-apps/radiology/lib/transforms/transforms.py @@ -14,6 +14,7 @@ import numpy as np import torch +from einops import rearrange from monai.config import KeysCollection, NdarrayOrTensor from monai.transforms import CropForeground, GaussianSmooth, Randomizable, Resize, ScaleIntensity, SpatialCrop from monai.transforms.transform import MapTransform, Transform @@ -505,3 +506,39 @@ def __call__(self, data: Mapping[Hashable, NdarrayOrTensor]) -> Dict[Hashable, N if d.get(cache_key) is None: d[cache_key] = copy.deepcopy(d[key]) return d + + +class OrientationGuidanceMultipleLabelDeepEditd(Transform): + def __init__(self, key_click, label_names=None): + """ + Convert the guidance to the RAS orientation + """ + self.label_names = label_names + self.key_click = key_click + + def transform_points(self, point, affine): + """ transform point to the coordinates of the transformed image + point: numpy array [bs, N, 3] + """ + bs, N = point.shape[:2] + point = np.concatenate((point,np.ones((bs, N,1))), axis=-1) + point = rearrange(point, 'b n d -> d (b n)') + point = affine @ point + point = rearrange(point, 'd (b n)-> b n d', b=bs)[:,:,:3] + return point + def __call__(self, data): + d: Dict = dict(data) + if self.key_click == 'click_coordinates': + for key_label, val_label in self.label_names.items(): + points = d.get(key_label, []) + if len(points) < 1: + continue + reoriented_points = self.transform_points(np.array(points)[None], + np.linalg.inv( + d['image_meta_dict']['affine'].numpy()) @ d['image_meta_dict']['original_affine'] + ) + # logging.info(f'Converted clicks: {reoriented_points[0]}') + d[key_label] = reoriented_points[0] + else: + logging.error('This transform only applies to click_coordinates') + return d \ No newline at end of file diff --git a/sample-apps/radiology/main.py b/sample-apps/radiology/main.py index f8ed414ec..d6c06c26c 100644 --- a/sample-apps/radiology/main.py +++ b/sample-apps/radiology/main.py @@ -287,7 +287,7 @@ def main(): parser = argparse.ArgumentParser() parser.add_argument("-s", "--studies", default=studies) - parser.add_argument("-m", "--model", default="segmentation_spleen") + parser.add_argument("-m", "--model", default="deepedit") parser.add_argument("-t", "--test", default="infer", choices=("train", "infer")) args = parser.parse_args() @@ -308,7 +308,7 @@ def main(): # Run on all devices for device in device_list(): - res = app.infer(request={"model": args.model, "image": image_id, "device": device}) + res = app.infer(request={"model": args.model, "image": image_id, "device": device, 'spleen': [[6, 6, 6], [9, 9, 9]]}) # res = app.infer( # request={"model": "vertebra_pipeline", "image": image_id, "device": device, "slicer": False} # ) From 2dbef4343e433606c3dd1e32fd69603e74de86ab Mon Sep 17 00:00:00 2001 From: Andres Date: Tue, 29 Aug 2023 19:13:57 +0100 Subject: [PATCH 2/7] Remove log sentence Signed-off-by: Andres --- sample-apps/radiology/lib/transforms/transforms.py | 1 - 1 file changed, 1 deletion(-) diff --git a/sample-apps/radiology/lib/transforms/transforms.py b/sample-apps/radiology/lib/transforms/transforms.py index 3c829dc4d..1d12d801e 100644 --- a/sample-apps/radiology/lib/transforms/transforms.py +++ b/sample-apps/radiology/lib/transforms/transforms.py @@ -537,7 +537,6 @@ def __call__(self, data): np.linalg.inv( d['image_meta_dict']['affine'].numpy()) @ d['image_meta_dict']['original_affine'] ) - # logging.info(f'Converted clicks: {reoriented_points[0]}') d[key_label] = reoriented_points[0] else: logging.error('This transform only applies to click_coordinates') From 726e0c9687a7e3ddccd55343eb243b3ce1319bb8 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 29 Aug 2023 18:19:33 +0000 Subject: [PATCH 3/7] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- sample-apps/radiology/lib/infers/deepedit.py | 4 ++-- .../radiology/lib/transforms/transforms.py | 23 ++++++++++--------- sample-apps/radiology/main.py | 4 +++- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/sample-apps/radiology/lib/infers/deepedit.py b/sample-apps/radiology/lib/infers/deepedit.py index 1285081ac..f8530fb29 100644 --- a/sample-apps/radiology/lib/infers/deepedit.py +++ b/sample-apps/radiology/lib/infers/deepedit.py @@ -11,6 +11,7 @@ from typing import Callable, Sequence, Union +from lib.transforms.transforms import OrientationGuidanceMultipleLabelDeepEditd from monai.apps.deepedit.transforms import ( AddGuidanceFromPointsDeepEditd, AddGuidanceSignalDeepEditd, @@ -34,7 +35,6 @@ from monailabel.interfaces.tasks.infer_v2 import InferType from monailabel.tasks.infer.basic_infer import BasicInferTask from monailabel.transform.post import Restored -from lib.transforms.transforms import OrientationGuidanceMultipleLabelDeepEditd class DeepEdit(BasicInferTask): @@ -87,7 +87,7 @@ def pre_transforms(self, data=None): if self.type == InferType.DEEPEDIT: t.extend( [ - OrientationGuidanceMultipleLabelDeepEditd(key_click='click_coordinates', label_names=self.labels), + OrientationGuidanceMultipleLabelDeepEditd(key_click="click_coordinates", label_names=self.labels), AddGuidanceFromPointsDeepEditd(ref_image="image", guidance="guidance", label_names=self.labels), Resized(keys="image", spatial_size=self.spatial_size, mode="area"), ResizeGuidanceMultipleLabelDeepEditd(guidance="guidance", ref_image="image"), diff --git a/sample-apps/radiology/lib/transforms/transforms.py b/sample-apps/radiology/lib/transforms/transforms.py index 1d12d801e..42702f605 100644 --- a/sample-apps/radiology/lib/transforms/transforms.py +++ b/sample-apps/radiology/lib/transforms/transforms.py @@ -517,27 +517,28 @@ def __init__(self, key_click, label_names=None): self.key_click = key_click def transform_points(self, point, affine): - """ transform point to the coordinates of the transformed image + """transform point to the coordinates of the transformed image point: numpy array [bs, N, 3] """ bs, N = point.shape[:2] - point = np.concatenate((point,np.ones((bs, N,1))), axis=-1) - point = rearrange(point, 'b n d -> d (b n)') + point = np.concatenate((point, np.ones((bs, N, 1))), axis=-1) + point = rearrange(point, "b n d -> d (b n)") point = affine @ point - point = rearrange(point, 'd (b n)-> b n d', b=bs)[:,:,:3] + point = rearrange(point, "d (b n)-> b n d", b=bs)[:, :, :3] return point + def __call__(self, data): d: Dict = dict(data) - if self.key_click == 'click_coordinates': + if self.key_click == "click_coordinates": for key_label, val_label in self.label_names.items(): points = d.get(key_label, []) if len(points) < 1: continue - reoriented_points = self.transform_points(np.array(points)[None], - np.linalg.inv( - d['image_meta_dict']['affine'].numpy()) @ d['image_meta_dict']['original_affine'] - ) + reoriented_points = self.transform_points( + np.array(points)[None], + np.linalg.inv(d["image_meta_dict"]["affine"].numpy()) @ d["image_meta_dict"]["original_affine"], + ) d[key_label] = reoriented_points[0] else: - logging.error('This transform only applies to click_coordinates') - return d \ No newline at end of file + logging.error("This transform only applies to click_coordinates") + return d diff --git a/sample-apps/radiology/main.py b/sample-apps/radiology/main.py index d6c06c26c..e34ccbb6a 100644 --- a/sample-apps/radiology/main.py +++ b/sample-apps/radiology/main.py @@ -308,7 +308,9 @@ def main(): # Run on all devices for device in device_list(): - res = app.infer(request={"model": args.model, "image": image_id, "device": device, 'spleen': [[6, 6, 6], [9, 9, 9]]}) + res = app.infer( + request={"model": args.model, "image": image_id, "device": device, "spleen": [[6, 6, 6], [9, 9, 9]]} + ) # res = app.infer( # request={"model": "vertebra_pipeline", "image": image_id, "device": device, "slicer": False} # ) From 1d367a04b8ee2429dff65561a4de1d5d6fa0c837 Mon Sep 17 00:00:00 2001 From: Andres Date: Mon, 4 Sep 2023 12:22:01 +0100 Subject: [PATCH 4/7] Remove unnecessary flag Signed-off-by: Andres --- sample-apps/radiology/lib/infers/deepedit.py | 2 +- .../radiology/lib/transforms/transforms.py | 24 ++++++++----------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/sample-apps/radiology/lib/infers/deepedit.py b/sample-apps/radiology/lib/infers/deepedit.py index 81172881d..43e50b8ec 100644 --- a/sample-apps/radiology/lib/infers/deepedit.py +++ b/sample-apps/radiology/lib/infers/deepedit.py @@ -88,7 +88,7 @@ def pre_transforms(self, data=None): if self.type == InferType.DEEPEDIT: t.extend( [ - OrientationGuidanceMultipleLabelDeepEditd(key_click="click_coordinates", label_names=self.labels), + OrientationGuidanceMultipleLabelDeepEditd(label_names=self.labels), AddGuidanceFromPointsDeepEditd(ref_image="image", guidance="guidance", label_names=self.labels), Resized(keys="image", spatial_size=self.spatial_size, mode="area"), ResizeGuidanceMultipleLabelDeepEditd(guidance="guidance", ref_image="image"), diff --git a/sample-apps/radiology/lib/transforms/transforms.py b/sample-apps/radiology/lib/transforms/transforms.py index 42702f605..390f2f223 100644 --- a/sample-apps/radiology/lib/transforms/transforms.py +++ b/sample-apps/radiology/lib/transforms/transforms.py @@ -509,12 +509,11 @@ def __call__(self, data: Mapping[Hashable, NdarrayOrTensor]) -> Dict[Hashable, N class OrientationGuidanceMultipleLabelDeepEditd(Transform): - def __init__(self, key_click, label_names=None): + def __init__(self, label_names=None): """ Convert the guidance to the RAS orientation """ self.label_names = label_names - self.key_click = key_click def transform_points(self, point, affine): """transform point to the coordinates of the transformed image @@ -529,16 +528,13 @@ def transform_points(self, point, affine): def __call__(self, data): d: Dict = dict(data) - if self.key_click == "click_coordinates": - for key_label, val_label in self.label_names.items(): - points = d.get(key_label, []) - if len(points) < 1: - continue - reoriented_points = self.transform_points( - np.array(points)[None], - np.linalg.inv(d["image_meta_dict"]["affine"].numpy()) @ d["image_meta_dict"]["original_affine"], - ) - d[key_label] = reoriented_points[0] - else: - logging.error("This transform only applies to click_coordinates") + for key_label, val_label in self.label_names.items(): + points = d.get(key_label, []) + if len(points) < 1: + continue + reoriented_points = self.transform_points( + np.array(points)[None], + np.linalg.inv(d["image_meta_dict"]["affine"].numpy()) @ d["image_meta_dict"]["original_affine"], + ) + d[key_label] = reoriented_points[0] return d From 44ea27fb2c223b3e2416f4ebf2366f93cfb6c6be Mon Sep 17 00:00:00 2001 From: Andres Date: Wed, 6 Sep 2023 00:28:41 +0100 Subject: [PATCH 5/7] Update for loop and affine argument Signed-off-by: Andres --- sample-apps/radiology/lib/transforms/transforms.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sample-apps/radiology/lib/transforms/transforms.py b/sample-apps/radiology/lib/transforms/transforms.py index 390f2f223..b6f37254f 100644 --- a/sample-apps/radiology/lib/transforms/transforms.py +++ b/sample-apps/radiology/lib/transforms/transforms.py @@ -528,13 +528,13 @@ def transform_points(self, point, affine): def __call__(self, data): d: Dict = dict(data) - for key_label, val_label in self.label_names.items(): + for key_label in self.label_names.keys(): points = d.get(key_label, []) if len(points) < 1: continue reoriented_points = self.transform_points( np.array(points)[None], - np.linalg.inv(d["image_meta_dict"]["affine"].numpy()) @ d["image_meta_dict"]["original_affine"], + np.linalg.inv(d["image"].meta["affine"].numpy()) @ d["image"].meta["original_affine"], ) d[key_label] = reoriented_points[0] return d From a224300462c4696479ff523c17ca79285cfe9ae3 Mon Sep 17 00:00:00 2001 From: Andres Date: Fri, 8 Sep 2023 15:46:17 +0100 Subject: [PATCH 6/7] Add ref_image arg Signed-off-by: Andres --- sample-apps/radiology/lib/infers/deepedit.py | 2 +- sample-apps/radiology/lib/transforms/transforms.py | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/sample-apps/radiology/lib/infers/deepedit.py b/sample-apps/radiology/lib/infers/deepedit.py index 43e50b8ec..cda4af2e5 100644 --- a/sample-apps/radiology/lib/infers/deepedit.py +++ b/sample-apps/radiology/lib/infers/deepedit.py @@ -88,7 +88,7 @@ def pre_transforms(self, data=None): if self.type == InferType.DEEPEDIT: t.extend( [ - OrientationGuidanceMultipleLabelDeepEditd(label_names=self.labels), + OrientationGuidanceMultipleLabelDeepEditd(ref_image="image", label_names=self.labels), AddGuidanceFromPointsDeepEditd(ref_image="image", guidance="guidance", label_names=self.labels), Resized(keys="image", spatial_size=self.spatial_size, mode="area"), ResizeGuidanceMultipleLabelDeepEditd(guidance="guidance", ref_image="image"), diff --git a/sample-apps/radiology/lib/transforms/transforms.py b/sample-apps/radiology/lib/transforms/transforms.py index b6f37254f..6b8488e33 100644 --- a/sample-apps/radiology/lib/transforms/transforms.py +++ b/sample-apps/radiology/lib/transforms/transforms.py @@ -509,10 +509,13 @@ def __call__(self, data: Mapping[Hashable, NdarrayOrTensor]) -> Dict[Hashable, N class OrientationGuidanceMultipleLabelDeepEditd(Transform): - def __init__(self, label_names=None): + def __init__(self, + ref_image: str, + label_names=None): """ Convert the guidance to the RAS orientation """ + self.ref_image = ref_image self.label_names = label_names def transform_points(self, point, affine): @@ -534,7 +537,7 @@ def __call__(self, data): continue reoriented_points = self.transform_points( np.array(points)[None], - np.linalg.inv(d["image"].meta["affine"].numpy()) @ d["image"].meta["original_affine"], + np.linalg.inv(d[self.ref_image].meta["affine"].numpy()) @ d[self.ref_image].meta["original_affine"], ) d[key_label] = reoriented_points[0] return d From 1f1b983092598c0f399a29d87e1775d88107250b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 8 Sep 2023 14:47:25 +0000 Subject: [PATCH 7/7] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- sample-apps/radiology/lib/transforms/transforms.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sample-apps/radiology/lib/transforms/transforms.py b/sample-apps/radiology/lib/transforms/transforms.py index 6b8488e33..e04471338 100644 --- a/sample-apps/radiology/lib/transforms/transforms.py +++ b/sample-apps/radiology/lib/transforms/transforms.py @@ -509,9 +509,7 @@ def __call__(self, data: Mapping[Hashable, NdarrayOrTensor]) -> Dict[Hashable, N class OrientationGuidanceMultipleLabelDeepEditd(Transform): - def __init__(self, - ref_image: str, - label_names=None): + def __init__(self, ref_image: str, label_names=None): """ Convert the guidance to the RAS orientation """