Skip to content
Snippets Groups Projects

Layered Surface Segmentation Feature

1 file
+ 95
48
Compare changes
  • Side-by-side
  • Inline
+ 95
48
@@ -23,9 +23,11 @@ class Session:
@@ -23,9 +23,11 @@ class Session:
self.min_margin = 10
self.min_margin = 10
self.n_layers = 4
self.n_layers = 4
self.is_inverted = False
self.is_inverted = False
 
self.l2d_obj = None
 
#TODO: Add here the slice positions
#TODO: Add here the slice positions
#TODO: Add here the l2d_obj ?
class Interface:
class Interface:
def __init__(self):
def __init__(self):
@@ -68,14 +70,23 @@ class Interface:
@@ -68,14 +70,23 @@ class Interface:
return session
return session
def update_session_slices(self, session, x_pos, y_pos, z_pos):
#TODO: Add here the update of the slices
#TODO: Add here the update of the slices
# def update_session_slices(self, session, x_pos, y_pos, z_pos):
return session
# return session
def update_session_parameters(self, session, delta, min_margin, n_layers, is_inverted):
def update_session_delta(self, session, delta):
session.delta = delta
session.delta = delta
 
return session
 
 
def update_session_min_margin(self, session, min_margin):
session.min_margin = min_margin
session.min_margin = min_margin
 
return session
 
 
def update_session_n_layers(self, session, n_layers):
session.n_layers = n_layers
session.n_layers = n_layers
 
return session
 
 
def update_session_is_inverted(self, session, is_inverted):
session.is_inverted = is_inverted
session.is_inverted = is_inverted
return session
return session
@@ -95,6 +106,14 @@ class Interface:
@@ -95,6 +106,14 @@ class Interface:
else:
else:
raise ValueError("Invalid path")
raise ValueError("Invalid path")
 
def set_relaunch_button(self):
 
# Sets the button to relaunch
 
return gr.update(
 
elem_classes="btn btn-run",
 
value=f"Relaunch",
 
interactive=True,
 
)
 
def set_spinner(self, message):
def set_spinner(self, message):
# spinner icon/shows the user something is happeing
# spinner icon/shows the user something is happeing
return gr.update(
return gr.update(
@@ -103,13 +122,6 @@ class Interface:
@@ -103,13 +122,6 @@ class Interface:
interactive=False,
interactive=False,
)
)
def set_relaunch_button(self):
return gr.update(
elem_classes="btn btn-run",
value=f"Relaunch",
interactive=True,
)
def create_interface(self):
def create_interface(self):
with gr.Blocks(css=self.css_path) as gradio_interface:
with gr.Blocks(css=self.css_path) as gradio_interface:
gr.Markdown(f"# {self.title}")
gr.Markdown(f"# {self.title}")
@@ -191,12 +203,15 @@ class Interface:
@@ -191,12 +203,15 @@ class Interface:
visible=True,
visible=True,
elem_classes="rounded",
elem_classes="rounded",
)
)
# Session
session = gr.State([])
session = gr.State([])
 
pipeline = Pipeline()
pipeline = Pipeline()
 
inputs = [base_path, explorer, delta, min_margin, n_layers, is_inverted]
inputs = [base_path, explorer, delta, min_margin, n_layers, is_inverted]
spinner_loading = gr.Text("Loading data...", visible=False)
spinner_loading = gr.Text("Loading data...", visible=False)
spinner_running = gr.Text("Running pipeline...", visible=False)
spinner_running = gr.Text("Running pipeline...", visible=False)
 
spinner_updating = gr.Text("Updating layers...", visible=False)
# fmt: off
# fmt: off
reload_base_path.click(fn=self.update_explorer,inputs=base_path, outputs=explorer)
reload_base_path.click(fn=self.update_explorer,inputs=base_path, outputs=explorer)
@@ -213,9 +228,35 @@ class Interface:
@@ -213,9 +228,35 @@ class Interface:
#TODO: Add here the update of the slices
#TODO: Add here the update of the slices
#TODO: Add here the update of the parameters
delta.change(
 
fn=self.update_session_delta, inputs=[session, delta], outputs=session, show_progress=False).success(
 
fn=self.set_spinner, inputs=spinner_updating, outputs=btn_run).then(
 
fn=pipeline.process_l2d, inputs=session, outputs=session).then(
 
fn=pipeline.plot_l2d_output, inputs=session, outputs=output_plot).then(
 
fn=self.set_relaunch_button, inputs=[], outputs=btn_run)
 
 
min_margin.change(
 
fn=self.update_session_min_margin, inputs=[session, min_margin], outputs=session, show_progress=False).success(
 
fn=self.set_spinner, inputs=spinner_updating, outputs=btn_run).then(
 
fn=pipeline.process_l2d, inputs=session, outputs=session).then(
 
fn=pipeline.plot_l2d_output, inputs=session, outputs=output_plot).then(
 
fn=self.set_relaunch_button, inputs=[], outputs=btn_run)
 
 
n_layers.change(
 
fn=self.update_session_n_layers, inputs=[session, n_layers], outputs=session, show_progress=False).success(
 
fn=self.set_spinner, inputs=spinner_updating, outputs=btn_run).then(
 
fn=pipeline.process_l2d, inputs=session, outputs=session).then(
 
fn=pipeline.plot_l2d_output, inputs=session, outputs=output_plot).then(
 
fn=self.set_relaunch_button, inputs=[], outputs=btn_run)
 
is_inverted.change(
 
fn=self.update_session_is_inverted, inputs=[session, is_inverted], outputs=session, show_progress=False).success(
 
fn=self.set_spinner, inputs=spinner_updating, outputs=btn_run).then(
 
fn=pipeline.process_l2d, inputs=session, outputs=session).then(
 
fn=pipeline.plot_l2d_output, inputs=session, outputs=output_plot).then(
 
fn=self.set_relaunch_button, inputs=[], outputs=btn_run)
# fmt: on
# fmt: on
 
return gradio_interface
return gradio_interface
@@ -223,7 +264,44 @@ class Pipeline:
@@ -223,7 +264,44 @@ class Pipeline:
def __init__(self):
def __init__(self):
self.figsize = (8, 8)
self.figsize = (8, 8)
 
def load_data(self, session):
 
try:
 
session.data = load(
 
session.file_path,
 
virtual_stack=session.virtual_stack,
 
dataset_name=session.dataset_name,
 
)
 
except Exception as error_message:
 
raise ValueError(
 
f"Failed to load the image: {error_message}"
 
) from error_message
 
 
return session
 
 
def process_l2d(self, session):
 
data = session.data
 
# TODO Add here some checks to be user data is 2D
 
 
if session.l2d_obj is None:
 
l2d_obj = l2d.Layers2d()
 
else:
 
l2d_obj = session.l2d_obj
 
 
l2d_obj.prepare_update(
 
data=data,
 
is_inverted=session.is_inverted,
 
delta=session.delta,
 
min_margin=session.min_margin,
 
n_layers=session.n_layers,
 
)
 
l2d_obj.update()
 
 
session.l2d_obj = l2d_obj
 
 
return session
 
def plot_input_img(self, session, cmap="Greys_r"):
def plot_input_img(self, session, cmap="Greys_r"):
 
plt.close()
plt.close()
fig, ax = plt.subplots(figsize=self.figsize)
fig, ax = plt.subplots(figsize=self.figsize)
@@ -237,7 +315,7 @@ class Pipeline:
@@ -237,7 +315,7 @@ class Pipeline:
def plot_l2d_output(self, session):
def plot_l2d_output(self, session):
l2d_obj = session.l2d_obj
l2d_obj = session.l2d_obj
fig, ax = qim3d.viz.layers2d.create_plot_of_2d_array(l2d_obj.get_data())
fig, ax = qim3d.viz.layers2d.create_plot_of_2d_array(l2d_obj.get_data_not_inverted())
data_lines = []
data_lines = []
for i in range(len(l2d_obj.get_segmentation_lines())):
for i in range(len(l2d_obj.get_segmentation_lines())):
@@ -252,38 +330,7 @@ class Pipeline:
@@ -252,38 +330,7 @@ class Pipeline:
fig.subplots_adjust(left=0, right=1, bottom=0, top=1)
fig.subplots_adjust(left=0, right=1, bottom=0, top=1)
return fig
return fig
def process_l2d(self, session):
data = session.data
# TODO Add here some checks to be user data is 2D
l2d_obj = l2d.Layers2d()
l2d_obj.prepare_update(
data=data,
is_inverted=session.is_inverted,
delta=session.delta,
min_margin=session.min_margin,
n_layers=session.n_layers,
)
l2d_obj.update()
session.l2d_obj = l2d_obj
return session
def load_data(self, session):
try:
session.data = load(
session.file_path,
virtual_stack=session.virtual_stack,
dataset_name=session.dataset_name,
)
except Exception as error_message:
raise ValueError(
f"Failed to load the image: {error_message}"
) from error_message
return session
def run_interface(host = "0.0.0.0"):
def run_interface(host = "0.0.0.0"):
gradio_interface = Interface().create_interface()
gradio_interface = Interface().create_interface()
Loading