Newer
Older
import tkinter as tknt
from typing import Union
import skimage.segmentation as sisg
from PIL import Image as image_t
from PIL import ImageTk as tk_image_t
class soma_validation_window_t:
__slots__ = (
"lmap",
"mip",
"mip_4_display",
"root",
"tk_image",
"canvas_image",
)
lmap: array_t
mip: array_t
mip_4_display: array_t
root: tknt.Tk
tk_image: tk_image_t
canvas_image: int
lmap: array_t,
mip_axis: int = -1,
color_version: bool = True,
with_cm: str = None,
):
"""
with_cm: "plasma" and "viridis" seem to be good options
"""
gfp_mip = nmpy.amax(gfp, axis=mip_axis)
gfp_mip *= 255.0 / nmpy.amax(gfp_mip)
mip = nmpy.amax(lmap, axis=mip_axis)
if with_cm is None:
mip_4_display = _ColoredVersion(mip)
else:
mip_4_display = _ColoredVersionFromColormap(mip, with_cm)
else:
mip_4_display = _ScaledVersion(mip)
root = tknt.Tk()
canvas_gfp = tknt.Canvas(root, width=gfp_mip.shape[1], height=gfp_mip.shape[0])
tk_image_gfp = _TkImageFromNumpyArray(gfp_mip, root)
_ = canvas_gfp.create_image(0, 0, anchor="nw", image=tk_image_gfp)
canvas = tknt.Canvas(root, width=mip.shape[1], height=mip.shape[0])
tk_image = _TkImageFromNumpyArray(mip_4_display, root)
canvas_image = canvas.create_image(0, 0, anchor="nw", image=tk_image)
done_button = tknt.Button(root, text="Done", command=root.quit)
canvas.bind("<Button-1>", self._DeleteSoma)
canvas.grid(row=0, column=1)
cursor_nfo.grid(row=1, column=0)
done_button.grid(row=1, column=1)
for field in self.__class__.__slots__:
setattr(self, field, eval(field))
def LaunchValidation(self) -> int:
self.root.destroy()
relabeled, _, _ = sisg.relabel_sequential(self.lmap)
self.lmap[...] = relabeled
return nmpy.amax(self.lmap)
def _DisplayLabel(self, event: tknt.EventType.Motion) -> None:
""""""
row = event.y
col = event.x
try:
label = self.mip[row, col]
except IndexError:
# This problem appeared when pack was replaced with grid. Setting ipad? and pad? to zero when adding the
# canvas to the grid did not solve it. Is this a bug in TkInter grid?
return
self.cursor_nfo.configure(text=f"Label:{label}@{row}x{col}")
def _DeleteSoma(self, event: tknt.EventType.ButtonPress) -> None:
""""""
row = event.y
col = event.x
try:
label = self.mip[row, col]
except IndexError:
# This problem appeared when pack was replaced with grid. Setting ipad? and pad? to zero when adding the
# canvas to the grid did not solve it. Is this a bug in TkInter grid?
return
if label > 0:
self.lmap[self.lmap == label] = 0
soma_bmap = self.mip == label
if self.mip_4_display.ndim == 1:
self.mip_4_display[soma_bmap] = 0
else:
for channel in range(self.mip_4_display.shape[2]):
self.mip_4_display[..., channel][soma_bmap] = 0
self.tk_image = _TkImageFromNumpyArray(self.mip_4_display, self.root)
self.canvas.itemconfigure(self.canvas_image, image=self.tk_image)
def _ScaledVersion(image: array_t, offset: int = 50) -> array_t:
"""
offset: Value of darkest non-background intensity
"""
scaling = (255.0 - offset) / nmpy.max(image)
output = scaling * image + offset
output[image == 0] = 0
return output.astype(nmpy.uint8)
def _ColoredVersion(image: array_t) -> array_t:
""""""
max_label = nmpy.amax(image)
half_length = int(round(0.5 * max_label))
shuffled_labels = labels[half_length:] + labels[:half_length]
shuffled_image = nmpy.zeros_like(image)
for label, shuffled_label in enumerate(shuffled_labels):
shuffled_image[image == label] = shuffled_label
output = nmpy.dstack((image, shuffled_image, max_label - image))
output = (255.0 / max_label) * output
output[image == 0] = 0
return output.astype(nmpy.uint8)
def _ColoredVersionFromColormap(image: array_t, colormap_name: str) -> array_t:
""""""
output = nmpy.zeros(image.shape + (3,), dtype=nmpy.uint8)
LinearValueToRGB = mpcm.get_cmap(colormap_name)
max_label = nmpy.amax(image)
for label in range(1, max_label + 1):
color_01 = LinearValueToRGB((label - 1.0) / (max_label - 1.0))
color_255 = nmpy.round(255.0 * nmpy.array(color_01[:3]))
output[image == label, :] = color_255
return output
def _TkImageFromNumpyArray(
array: array_t, parent: Union[tknt.Widget, tknt.Tk]
) -> tk_image_t:
""""""
pil_image = image_t.fromarray(array)
output = tk_image_t.PhotoImage(master=parent, image=pil_image)
return output