Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Streamlined head surface creation #877

Merged
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
e38230f
ADD: New page in the coregistration panel for easier head surface cre…
henrikkauppi Jan 15, 2025
2ba15ca
ADD: Button in coregistration to create head surface from mask and th…
henrikkauppi Jan 15, 2025
a1b1827
ADD: Streamlined head surface creation also removes non-visible faces…
henrikkauppi Jan 16, 2025
2c227a6
ADD: Bypass plugin GUI when removing non-visible faces in streamlined…
henrikkauppi Jan 17, 2025
1684397
MOD: Rename 'Head' page in coregistration panel as 'Surface' to be mo…
henrikkauppi Jan 17, 2025
eb365d0
Merge branch 'invesalius:master' into streamlined-head-surface-creation
henrikkauppi Jan 29, 2025
160981e
ADD: checkboxes to control the steps of the streamlined head surface …
henrikkauppi Jan 29, 2025
e354370
ADD: Brain segmentation step to the streamlined head surface creation
henrikkauppi Feb 6, 2025
82ba9b2
Merge branch 'invesalius:master' into streamlined-head-surface-creation
henrikkauppi Feb 6, 2025
8d11ed9
MOD: Show the navigation panel by default when opening InVesalius in …
henrikkauppi Feb 14, 2025
6799dd8
MOD: Set default colors and transparency for the created scalp and br…
henrikkauppi Feb 14, 2025
d69b7a7
MOD: Automate the brain segmentation process with default parameters
henrikkauppi Feb 14, 2025
dbaf95a
Merge branch 'invesalius:master' into streamlined-head-surface-creation
henrikkauppi Feb 25, 2025
6f3bd39
MOD: Integrate 'remove non-visible faces'-plugin into InVesalius and …
henrikkauppi Feb 25, 2025
79e42da
MOD: name created surfaces as scalp or brain
henrikkauppi Feb 25, 2025
4153030
MOD: keep the largest surface when creating a brain surface
henrikkauppi Feb 25, 2025
4eebbe3
ADD: Imports page to the coregistration panel for easier image and pr…
henrikkauppi Feb 28, 2025
70224a2
ADD: smooth surface and FIX: small bugs
rmatsuda Mar 4, 2025
5883d84
RUFF
rmatsuda Mar 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions invesalius/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -820,6 +820,15 @@
BRAIN_INTENSITY_MTMS = 8
BRAIN_UUID = 9

# Page order in the coregistration panel

HEAD_PAGE = 0
IMAGE_PAGE = 1
TRACKER_PAGE = 2
REFINE_PAGE = 3
STYLUS_PAGE = 4
STIMULATOR_PAGE = 5

# ------------ Navigation defaults -------------------

MARKER_COLOUR = (1.0, 1.0, 0.0)
Expand Down
3 changes: 3 additions & 0 deletions invesalius/data/surface.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,13 +315,16 @@ def OnLargestSurface(self):
Create a new surface, based on largest part of the last
selected surface.
"""
progress_dialog = dialogs.SelectLargestSurfaceProgressWindow()
progress_dialog.Update()
index = self.last_surface_index
proj = prj.Project()
surface = proj.surface_dict[index]

new_polydata = pu.SelectLargestPart(surface.polydata)
new_index = self.CreateSurfaceFromPolydata(new_polydata)
Publisher.sendMessage("Show single surface", index=new_index, visibility=True)
progress_dialog.Close()

def OnImportCustomBinFile(self, filename):
import os
Expand Down
25 changes: 21 additions & 4 deletions invesalius/gui/deep_learning_seg_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,14 @@

class DeepLearningSegmenterDialog(wx.Dialog):
def __init__(
self, parent, title, has_torch=True, has_plaidml=True, has_theano=True, segmenter=None
self,
parent,
title,
auto_segment=False,
has_torch=True,
has_plaidml=True,
has_theano=True,
segmenter=None,
):
wx.Dialog.__init__(
self,
Expand All @@ -68,6 +75,7 @@ def __init__(
# self.pg_dialog = None
self.torch_devices = TORCH_DEVICES
self.plaidml_devices = PLAIDML_DEVICES
self.auto_segment = auto_segment

self.backends = backends

Expand All @@ -87,6 +95,9 @@ def __init__(
self.OnSetBackend()
self.HideProgress()

if self.auto_segment:
self.OnSegment(self)

def _init_gui(self):
self.cb_backends = wx.ComboBox(
self,
Expand Down Expand Up @@ -332,6 +343,10 @@ def AfterSegment(self):
self.elapsed_time_timer.Stop()
self.apply_segment_threshold()

if self.auto_segment:
self.OnClose(self)
Publisher.sendMessage("Brain segmentation completed")

def SetProgress(self, progress):
self.progress.SetValue(int(progress * 100))
wx.GetApp().Yield()
Expand Down Expand Up @@ -361,8 +376,9 @@ def OnTickTimer(self, evt):
if progress == np.inf:
progress = 1
self.AfterSegment()
progress = max(0, min(progress, 1))
self.SetProgress(float(progress))
else:
progress = max(0, min(progress, 1))
self.SetProgress(float(progress))

def OnClose(self, evt):
# self.segmenter.stop = True
Expand Down Expand Up @@ -393,14 +409,15 @@ def ShowProgress(self):


class BrainSegmenterDialog(DeepLearningSegmenterDialog):
def __init__(self, parent):
def __init__(self, parent, auto_segment=False):
super().__init__(
parent=parent,
title=_("Brain segmentation"),
has_torch=True,
has_plaidml=True,
has_theano=True,
segmenter=segment.BrainSegmentProcess,
auto_segment=auto_segment,
)


Expand Down
7 changes: 6 additions & 1 deletion invesalius/gui/default_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,6 @@ def __init__(self, parent):
elif name == _("Configure 3D surface"):
self.__id_surface = item.GetId()

fold_panel.Expand(fold_panel.GetFoldPanel(0))
self.fold_panel = fold_panel
self.image_list = image_list

Expand All @@ -342,6 +341,12 @@ def __init__(self, parent):
self.SetSizerAndFit(sizer)
self.__bind_events()

# Show the navigation panel in navigation mode; otherwise, show the imports panel
if mode == const.MODE_NAVIGATOR:
self.fold_panel.Expand(self.fold_panel.GetFoldPanel(1))
else:
self.fold_panel.Expand(self.fold_panel.GetFoldPanel(0))

def __bind_events(self):
session = ses.Session()
mode = session.GetConfig("mode")
Expand Down
38 changes: 38 additions & 0 deletions invesalius/gui/dialogs.py
Original file line number Diff line number Diff line change
Expand Up @@ -1978,6 +1978,44 @@ def GetValue(self) -> Dict[str, Union[str, int, bool]]:
}


class SelectLargestSurfaceProgressWindow:
def __init__(self):
title = "InVesalius 3"
message = "Creating a new surface form the largest contiguous region..."
style = wx.PD_APP_MODAL | wx.PD_CAN_ABORT
parent = wx.GetApp().GetTopWindow()
self.dlg = wx.ProgressDialog(title, message, parent=parent, style=style)
self.dlg.Show()

def Update(self, msg: Optional[str] = None, value=None) -> None:
if msg is None:
self.dlg.Pulse()
else:
self.dlg.Pulse(msg)

def Close(self) -> None:
self.dlg.Destroy()


class RemoveNonVisibleFacesProgressWindow:
def __init__(self):
title = "InVesalius 3"
message = "Removing non-visible faces..."
style = wx.PD_APP_MODAL | wx.PD_CAN_ABORT
parent = wx.GetApp().GetTopWindow()
self.dlg = wx.ProgressDialog(title, message, parent=parent, style=style)
self.dlg.Show()

def Update(self, msg: Optional[str] = None, value=None) -> None:
if msg is None:
self.dlg.Pulse()
else:
self.dlg.Pulse(msg)

def Close(self) -> None:
self.dlg.Destroy()


class SurfaceTransparencyDialog(wx.Dialog):
def __init__(
self, parent: Optional[wx.Window], surface_index: int = 0, transparency: int = 0
Expand Down
Loading
Loading