Skip to content

Commit e6e87de

Browse files
allow metadata based scaling of images
1 parent d75cd6b commit e6e87de

File tree

2 files changed

+57
-4
lines changed

2 files changed

+57
-4
lines changed

src/fractal_feature_explorer/pages/filters_page/_scatter_filter.py

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,13 @@ def view_point(point: int, feature_df: pl.DataFrame) -> None:
5656

5757
channels = container.channel_labels
5858
if len(channels) > 1:
59-
channel = st.selectbox(
59+
channel_sel = st.selectbox(
6060
label="Select channel",
6161
options=channels,
6262
index=0,
6363
help="Select the channel to display",
6464
)
65-
channel = channels.index(channel)
65+
channel = channels.index(channel_sel)
6666
else:
6767
channel = 0
6868

@@ -108,7 +108,28 @@ def view_point(point: int, feature_df: pl.DataFrame) -> None:
108108
index=0,
109109
help="Select the level to display",
110110
)
111-
111+
112+
image_scaling = st.selectbox(
113+
label="Image Scaling",
114+
options=["Metadata", "Min-Max", "Custom"],
115+
index=0,
116+
help="Select the image scaling",
117+
)
118+
119+
vis_meta = image.channels_meta.channels[channel].channel_visualisation
120+
if image_scaling == "Custom":
121+
vis_meta = image.channels_meta.channels[channel].channel_visualisation
122+
max_value = float(max(vis_meta.end * 1.5, 255.))
123+
min_intensity, max_intensity = st.slider(
124+
label="Intensity Range",
125+
min_value=0.,
126+
max_value=max_value,
127+
value=(float(vis_meta.start), float(vis_meta.end)),
128+
)
129+
else:
130+
min_intensity = vis_meta.start
131+
max_intensity = vis_meta.end
132+
112133
try:
113134
image = get_single_label_image(
114135
image_url=point_dict["image_url"],
@@ -120,6 +141,9 @@ def view_point(point: int, feature_df: pl.DataFrame) -> None:
120141
t_slice=t_slice,
121142
show_label=show_label,
122143
zoom_factor=zoom_factor,
144+
scaling_mode=image_scaling,
145+
min_intensity=min_intensity,
146+
max_intensity=max_intensity,
123147
)
124148

125149
st.image(image, width=500)

src/fractal_feature_explorer/utils/ngio_io_caches.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,27 @@ def _get_label_array(
351351
return label_array
352352

353353

354+
def scale_image_intensity(
355+
image_array: np.ndarray,
356+
scaling_mode: str = "Metadata",
357+
min_intensity: int | float = 0,
358+
max_intensity: int | float = 255,
359+
) -> np.ndarray:
360+
"""
361+
Scale the image intensity based on the selected scaling mode.
362+
"""
363+
if scaling_mode not in ["Metadata", "Min-Max", "Custom"]:
364+
raise ValueError(f"Invalid scaling mode: {scaling_mode}")
365+
366+
if scaling_mode != "Min-Max":
367+
image_array = np.clip(image_array, min_intensity, max_intensity)
368+
369+
min_intensity = image_array.min()
370+
max_intensity = image_array.max()
371+
image_array = (image_array - min_intensity) / (max_intensity - min_intensity)
372+
return image_array * 255
373+
374+
354375
def get_single_label_image(
355376
image_url: str,
356377
ref_label: str,
@@ -361,6 +382,9 @@ def get_single_label_image(
361382
level_path: str = "0",
362383
show_label: bool = True,
363384
zoom_factor: float = 1,
385+
scaling_mode: str = "Metadata",
386+
min_intensity: int | float = 0,
387+
max_intensity: int | float = 255,
364388
) -> np.ndarray:
365389
"""
366390
Get the region of interest from the image url
@@ -378,7 +402,12 @@ def get_single_label_image(
378402
fractal_token=fractal_token,
379403
)
380404
image_array = image_array.squeeze()
381-
image_array = np.clip(image_array, 0, 255)
405+
image_array = scale_image_intensity(
406+
image_array,
407+
scaling_mode=scaling_mode,
408+
min_intensity=min_intensity,
409+
max_intensity=max_intensity,
410+
).astype(np.uint8)
382411

383412
image_rgba = np.empty(
384413
(image_array.shape[0], image_array.shape[1], 4), dtype=np.uint8

0 commit comments

Comments
 (0)