Skip to content

Commit baea714

Browse files
committed
ENH: Add get_roi_image method
Return the NgffImage for the current ROI. Users can select the scale or specific image data to return. Defaults to the first image loaded at the currently loaded scale.
1 parent 9cbc5b5 commit baea714

File tree

2 files changed

+40
-3
lines changed

2 files changed

+40
-3
lines changed

itkwidgets/_initialization_params.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ def parse_input_data(init_data_kwargs):
7373
return inputs
7474

7575

76-
def build_init_data(input_data):
76+
def build_init_data(input_data, stores):
7777
result= None
7878
for input_type in DATA_OPTIONS:
7979
data = input_data.pop(input_type, None)
@@ -83,12 +83,15 @@ def build_init_data(input_data):
8383
if render_type is RenderType.IMAGE:
8484
if input_type == 'label_image':
8585
result = _get_viewer_image(data, label=True)
86+
stores['LabelImage'] = result
8687
render_type = RenderType.LABELIMAGE
8788
elif input_type == 'fixed_image':
8889
result = _get_viewer_image(data)
90+
stores['Fixed'] = result
8991
render_type = RenderType.FIXEDIMAGE
9092
else:
9193
result = _get_viewer_image(data, label=False)
94+
stores['Image'] = result
9295
elif render_type is RenderType.POINT_SET:
9396
result = _get_viewer_point_set(data)
9497
if result is None:

itkwidgets/viewer.py

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from inspect import isawaitable
66
from typing import List, Union, Tuple
77
from IPython.display import display, HTML
8+
from ngff_zarr import from_ngff_zarr, to_ngff_image, NgffImage
89
import uuid
910

1011
from ._type_aliases import Gaussians, Style, Image, PointSet
@@ -136,9 +137,10 @@ def __init__(
136137
self, ui_collapsed=True, rotate=False, ui="pydata-sphinx", **add_data_kwargs
137138
):
138139
"""Create a viewer."""
140+
self.stores = {}
139141
self.name = self.__str__()
140142
input_data = parse_input_data(add_data_kwargs)
141-
data = build_init_data(input_data)
143+
data = build_init_data(input_data, self.stores)
142144
if compare := input_data.get('compare'):
143145
data['compare'] = compare
144146
if ENVIRONMENT is not Env.HYPHA:
@@ -213,6 +215,7 @@ def set_image(self, image: Image, name: str = 'Image'):
213215
render_type = _detect_render_type(image, 'image')
214216
if render_type is RenderType.IMAGE:
215217
image = _get_viewer_image(image, label=False)
218+
self.stores[name] = image
216219
if ENVIRONMENT is Env.HYPHA:
217220
self.image = image
218221
svc_name = f'{self.workspace}/itkwidgets-server:data-set'
@@ -323,6 +326,36 @@ async def get_current_scale(self):
323326
"""
324327
return await self.viewer_rpc.itk_viewer.getLoadedScale()
325328

329+
@fetch_value
330+
async def get_roi_image(self, scale: int = -1, name: str = 'Image') -> NgffImage:
331+
"""Get the image for the current ROI.
332+
333+
:param scale: scale of the primary image to get the slices for the
334+
current roi. -1, the default, uses the current scale.
335+
:type scale: int
336+
:param name: Name of the loaded image data to use. 'Image', the
337+
default, selects the first loaded image.
338+
:type name: str
339+
340+
:return: roi_image
341+
:rtype: NgffImage
342+
"""
343+
roi_slices = await self.get_roi_slice(scale)
344+
roi_region = await self.get_roi_region()
345+
if store := self.stores.get(name):
346+
multiscales = from_ngff_zarr(store)
347+
loaded_image = multiscales.images[scale]
348+
roi_data = loaded_image.data[roi_slices]
349+
return to_ngff_image(
350+
roi_data,
351+
dims=loaded_image.dims,
352+
scale=loaded_image.scale,
353+
translation=roi_region[0],
354+
name=name,
355+
axes_units=loaded_image.axes_units
356+
)
357+
raise ValueError(f'No image data found for {name}.')
358+
326359
@fetch_value
327360
async def get_roi_region(self):
328361
"""Get the current region of interest in world / physical space.
@@ -339,7 +372,7 @@ async def get_roi_region(self):
339372
return [{ 'x': x0, 'y': y0, 'z': z0 }, { 'x': x1, 'y': y1, 'z': z1 }]
340373

341374
@fetch_value
342-
async def get_roi_slice(self, scale=-1):
375+
async def get_roi_slice(self, scale: int = -1):
343376
"""Get the current region of interest as Python slice objects for the
344377
current resolution of the primary image. The result is in the order:
345378
@@ -395,6 +428,7 @@ def set_label_image(self, label_image: Image):
395428
render_type = _detect_render_type(label_image, 'image')
396429
if render_type is RenderType.IMAGE:
397430
label_image = _get_viewer_image(label_image, label=True)
431+
self.stores['LabelImage'] = label_image
398432
if ENVIRONMENT is Env.HYPHA:
399433
self.label_image = label_image
400434
svc_name = f"{self.workspace}/itkwidgets-server:data-set"

0 commit comments

Comments
 (0)