From aade8740275447090fb2f20555e277cd2e6de3bf Mon Sep 17 00:00:00 2001 From: Christopher Rhodes <christopher.rhodes@embl.de> Date: Tue, 10 Oct 2023 14:36:36 +0200 Subject: [PATCH] Chasing down bug in overlay annotations --- extensions/chaeo/annotators.py | 5 ++-- .../chaeo/examples/batch_run_patches.py | 2 +- extensions/chaeo/products.py | 12 ++++++--- extensions/chaeo/tests/test_zstack.py | 10 +++++++ extensions/chaeo/workflows.py | 26 ++++++++++++++++--- 5 files changed, 44 insertions(+), 11 deletions(-) diff --git a/extensions/chaeo/annotators.py b/extensions/chaeo/annotators.py index 3e84d0b1..0c25647e 100644 --- a/extensions/chaeo/annotators.py +++ b/extensions/chaeo/annotators.py @@ -58,11 +58,10 @@ def draw_box_on_patch(patch, bbox, linewidth=1): draw.rectangle([(x0, y0), (x1, y1)], outline='white', width=linewidth) return np.array(pilimg) -def draw_contours_on_patch(patch, contours, offset, linewidth=1): +def draw_contours_on_patch(patch, contours, linewidth=1): assert len(patch.shape) == 2 pilimg = Image.fromarray(patch) # drawing modifies array in-place draw = ImageDraw.Draw(pilimg) - x0, y0 = offset for co in contours: - draw.line([(p[1] + y0, p[0] + x0) for p in co], width=linewidth) + draw.line([(p[1], p[0]) for p in co], width=linewidth) return np.array(pilimg) \ No newline at end of file diff --git a/extensions/chaeo/examples/batch_run_patches.py b/extensions/chaeo/examples/batch_run_patches.py index f2fd45d9..0c27af40 100644 --- a/extensions/chaeo/examples/batch_run_patches.py +++ b/extensions/chaeo/examples/batch_run_patches.py @@ -38,7 +38,7 @@ if __name__ == '__main__': ma = re.match(pattern, ff.stem) print(ff) - if not ff.suffix.upper () == '.CZI': + if not ff.suffix.upper() == '.CZI': continue if int(ma.groups()[1]) > 10: # skip second half of set continue diff --git a/extensions/chaeo/products.py b/extensions/chaeo/products.py index 006244e2..bab25537 100644 --- a/extensions/chaeo/products.py +++ b/extensions/chaeo/products.py @@ -146,16 +146,22 @@ def export_patches_from_zstack( if kwargs.get('draw_mask'): mci = kwargs.get('mask_channel', 0) + mask = np.zeros(patch.shape[0:2], dtype=bool) + mask[sp_sl[0:2]] = mi['mask'] for zi in range(0, patch.shape[3]): - patch[sp_sl][:, :, mci, zi] = np.invert(mi['mask']) * patch[sp_sl][:, :, mci, zi] + patch[:, :, mci, zi] = np.invert(mask) * patch[:, :, mci, zi] if kwargs.get('draw_contour'): mci = kwargs.get('contour_channel', 0) + mask = np.zeros(patch.shape[0:2], dtype=bool) + try: + mask[sp_sl[0:2]] = mi['mask'] + except Exception: + a=1 for zi in range(0, patch.shape[3]): patch[:, :, mci, zi] = draw_contours_on_patch( patch[:, :, mci, zi], - find_contours(mi['mask']), - offset=(x0, y0) + find_contours(mask) ) if pad_to: diff --git a/extensions/chaeo/tests/test_zstack.py b/extensions/chaeo/tests/test_zstack.py index 89e69db1..35f14666 100644 --- a/extensions/chaeo/tests/test_zstack.py +++ b/extensions/chaeo/tests/test_zstack.py @@ -132,6 +132,11 @@ class TestZStackDerivedDataProducts(unittest.TestCase): ) self.assertGreaterEqual(len(files), 1) + def test_make_multichannel_2d_patches_with_mask_overlay(self): + zmask, meta = self.test_zmask_makes_correct_boxes( + filters={'area': (1e3, 1e4)}, + expand_box_by=(128, 2) + ) files = export_multichannel_patches_from_zstack( output_path / '2d_patches_chlorophyl_mask_overlay', InMemoryDataAccessor(self.stack.data), @@ -144,6 +149,11 @@ class TestZStackDerivedDataProducts(unittest.TestCase): ) self.assertGreaterEqual(len(files), 1) + def test_make_multichannel_2d_patches_with_contour_overlay(self): + zmask, meta = self.test_zmask_makes_correct_boxes( + filters={'area': (1e3, 1e4)}, + expand_box_by=(128, 2) + ) files = export_multichannel_patches_from_zstack( output_path / '2d_patches_chlorophyl_contour_overlay', InMemoryDataAccessor(self.stack.data), diff --git a/extensions/chaeo/workflows.py b/extensions/chaeo/workflows.py index 7f2df928..6b23ca80 100644 --- a/extensions/chaeo/workflows.py +++ b/extensions/chaeo/workflows.py @@ -3,7 +3,7 @@ from typing import Dict from extensions.ilastik.models import IlastikPixelClassifierModel from extensions.chaeo.annotators import draw_boxes_on_3d_image -from extensions.chaeo.products import export_patches_from_zstack, export_patch_masks_from_zstack +from extensions.chaeo.products import export_patches_from_zstack, export_patch_masks_from_zstack, export_multichannel_patches_from_zstack from extensions.chaeo.zmask import build_zmask_from_object_mask, project_stack_from_focal_points from model_server.accessors import generate_file_accessor, InMemoryDataAccessor, write_accessor_data_to_file from model_server.workflows import Timer @@ -78,16 +78,34 @@ def export_patches_from_multichannel_zstack( ) ti.click('export_3d_patches') + # if export_2d_patches: + # files = export_patches_from_zstack( + # Path(where_output) / '2d_patches', + # stack.get_one_channel_data(patches_channel), + # zmask_meta, + # prefix=fstem, + # draw_bounding_box=False, + # rescale_clip=0.0, + # make_3d=False, + # focus_metric='max_sobel', + # ) + # ti.click('export_2d_patches') + if export_2d_patches: - files = export_patches_from_zstack( - Path(where_output) / '2d_patches', - stack.get_one_channel_data(patches_channel), + files = export_multichannel_patches_from_zstack( + Path(where_output) / '2d_patches_chlorophyl_contour', + stack, zmask_meta, prefix=fstem, draw_bounding_box=False, rescale_clip=0.0, make_3d=False, focus_metric='max_sobel', + ch_white=4, + ch_rgb_overlay=(3, None, None), + draw_contour=True, + contour_channel=1, + overlay_gain=(0.1, 1.0, 1.0) ) ti.click('export_2d_patches') -- GitLab