Skip to content
Snippets Groups Projects
Commit 4d16baa5 authored by Christopher Randolph Rhodes's avatar Christopher Randolph Rhodes
Browse files

Split out patch/patch mask creation for file export; implemented and test...

Split out patch/patch mask creation for file export; implemented and test accessor abstraction for patch arrays
parent 5e9f9b72
No related branches found
No related tags found
No related merge requests found
import numpy as np
from model_server.accessors import InMemoryDataAccessor
class MonoPatchStack(InMemoryDataAccessor):
def __init__(self, data):
"""
A sequence of n monochrome images of the same size
:param data: either np.ndarray of dimensions YXn, or a list of np.ndarrays of size YX
"""
if isinstance(data, np.ndarray): # interpret as YXZ
assert len(data.shape) == 3
self._data = np.expand_dims(data, 2)
elif isinstance(data, list): # list of YX patches
self._data = np.expand_dims(
np.moveaxis(
np.array(data),
[1, 2, 0],
[0, 1, 2]),
2
)
else:
raise InvalidDataForPatchStackError(f'Cannot create accessor from {type(data)}')
def make_tczyx(self):
assert self.chroma == 1
tyx = np.moveaxis(
self.data[:, :, 0, :], # YX(C)Z
[2, 0, 1],
[0, 1, 2]
)
return np.expand_dims(tyx, (1, 2))
@property
def count(self):
return self.nz
def iat(self, i):
return self.data[:, :, 0, i]
def get_list(self):
n = self.nz
return [self.data[:, :, 0, zi] for zi in range(0, n)]
class Error(Exception):
pass
class InvalidDataForPatchStackError(Error):
pass
\ No newline at end of file
......@@ -9,6 +9,7 @@ from skimage.io import imsave
from skimage.measure import find_contours, shannon_entropy
from tifffile import imwrite
from extensions.chaeo.accessors import MonoPatchStack
from extensions.chaeo.annotators import draw_box_on_patch, draw_contours_on_patch
from model_server.accessors import GenericImageDataAccessor, InMemoryDataAccessor
from model_server.process import pad, rescale, resample_to_8bit
......@@ -55,16 +56,13 @@ def _write_patch_to_file(where, fname, data):
else:
raise Exception(f'Unsupported file extension: {ext}')
def export_patch_masks_from_zstack(
where: Path,
def get_patch_masks_from_zmask_meta(
stack: GenericImageDataAccessor,
zmask_meta: list,
pad_to: int = 256,
prefix='mask',
):
exported = []
) -> MonoPatchStack:
patches = []
for mi in zmask_meta:
obj = mi['info']
sl = mi['slice']
rbb = mi['relative_bounding_box']
......@@ -82,27 +80,48 @@ def export_patch_masks_from_zstack(
if pad_to:
patch = pad(patch, pad_to)
patches.append(patch)
return MonoPatchStack(patches)
def export_patch_masks_from_zstack(
where: Path,
stack: GenericImageDataAccessor,
zmask_meta: list,
pad_to: int = 256,
prefix='mask',
**kwargs
):
patches_acc = get_patch_masks_from_zmask_meta(
stack,
zmask_meta,
pad_to=pad_to,
**kwargs
)
assert len(zmask_meta) == patches_acc.count
exported = []
for i in range(0, len(zmask_meta)):
mi = zmask_meta[i]
obj = mi['info']
patch = patches_acc.iat(i)
ext = 'png'
fname = f'{prefix}-la{obj.label:04d}-zi{obj.zi:04d}.{ext}'
_write_patch_to_file(where, fname, patch)
exported.append(fname)
return exported
def export_patches_from_zstack(
where: Path,
def get_patches_from_zmask_meta(
stack: GenericImageDataAccessor,
zmask_meta: list,
rescale_clip: float = 0.0,
pad_to: int = 256,
make_3d: bool = False,
prefix='patch',
focus_metric: str = None,
**kwargs
):
exported = []
) -> MonoPatchStack:
patches = []
for mi in zmask_meta:
obj = mi['info']
sl = mi['slice']
rbb = mi['relative_bounding_box']
idx = mi['df_index']
......@@ -177,6 +196,37 @@ def export_patches_from_zstack(
if pad_to:
patch = pad(patch, pad_to)
patches.append(patch)
return MonoPatchStack(patches)
def export_patches_from_zstack(
where: Path,
stack: GenericImageDataAccessor,
zmask_meta: list,
rescale_clip: float = 0.0,
pad_to: int = 256,
make_3d: bool = False,
prefix='patch',
focus_metric: str = None,
**kwargs
):
patches_acc = get_patches_from_zmask_meta(
stack,
zmask_meta,
rescale_clip=rescale_clip,
pad_to=pad_to,
make_3d=make_3d,
focus_metric=focus_metric,
**kwargs
)
assert len(zmask_meta) == patches_acc.count
exported = []
for i in range(0, len(zmask_meta)):
mi = zmask_meta[i]
patch = patches_acc.iat(i)
obj = mi['info']
idx = mi['df_index']
ext = 'tif' if make_3d else 'png'
fname = f'{prefix}-la{obj.label:04d}-zi{obj.zi:04d}.{ext}'
......
import unittest
import numpy as np
from extensions.chaeo.accessors import MonoPatchStack
class TestCziImageFileAccess(unittest.TestCase):
def setUp(self) -> None:
pass
def test_make_patch_stack_from_list(self):
w = 256
h = 512
n = 4
acc = MonoPatchStack(np.random.rand(h, w, n))
assert acc.count == n
assert acc.hw == (h, w)
def test_make_patch_stack_from_3d_array(self):
w = 256
h = 512
n = 4
acc = MonoPatchStack([np.random.rand(h, w) for _ in range(0, 4)])
assert acc.count == n
assert acc.hw == (h, w)
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment