From 251882dbf0892fb17227124873be7e38323fc12d Mon Sep 17 00:00:00 2001 From: lpbsscientist <lpbsscientist@gmail.com> Date: Thu, 14 Jan 2021 11:04:24 +0100 Subject: [PATCH] Sahand: New Merge Cells tool. --- GUI_main.py | 76 ++++++++++++++++++++++++++++++++++++++++++++- init/InitButtons.py | 12 ++++++- init/InitLayout.py | 1 + 3 files changed, 87 insertions(+), 2 deletions(-) diff --git a/GUI_main.py b/GUI_main.py index f755688..1dbc1f8 100644 --- a/GUI_main.py +++ b/GUI_main.py @@ -228,9 +228,12 @@ class App(QMainWindow): self.button_hidemask = QCheckBox('Hide mask') self.buttonlist.append(self.button_hidemask) - self.button_split = QPushButton('Split Cell') + self.button_split = QPushButton('Split cell') self.buttonlist.append(self.button_split) + self.button_mergewithneighbors = QPushButton('Merge cells') + self.buttonlist.append(self.button_mergewithneighbors) + self.button_nextframe = QPushButton("Next time frame") self.buttonlist.append(self.button_nextframe) @@ -1475,6 +1478,77 @@ class App(QMainWindow): self.SaveMask() + def MergeWithNeighbors(self): + """This function is called when the button Merge With Neighbors is + clicked. It displays the instructions on the status bar. + And if the user clicks in the graph where the current mask is displayed + it connects the event of the click (meaning that user has clicked on + one cell) to the function self.PerformMergeWithNeighbors. + This function will then merge the cell selected by the user with + the click with all (touching) neighbors. + """ + + # displaying the instructions on the statusbar + self.WriteStatusBar(( + 'Left-click to select cell, right-click to abort.')) + + # disables all the buttons + self.Disable(self.button_mergewithneighbors) + + # connects the event "press mouse button" in the matplotlib plot + # (picture) to the function self.PerformMergeWithNeighbors + self.id = self.m.mpl_connect('button_press_event', self.PerformMergeWithNeighbors) + + + def PerformMergeWithNeighbors(self, event): + """This function is called after the user has selected + the button Merge With Neighbors and clicked in the picture to select + the desired cell to start the merger. + + It first deconnects the mouse click event in matplotlib with this + function to not generate any other dialog window. + + It then tests if the click is inside the matplotlib plot (if it is + outside it equals to None) and if it is the current and editable plot + (the one in the middle of the gui, self.m.ax) + + If is true, then it sets the coordinates to int. and creates a dialog + window where the user is asked to type a value to set it to the cell. + + If the user presses ok, it tests if the entry is valid (>0 and not + empty) and looks for the old cell value and replaces it. And then + it updates the plot such that the result of the change can be seen. + """ + # the function is disconnected from the matplotlib event. + self.m.mpl_disconnect(self.id) + + # test if the button is a left click and if the coordinates + # chosen by the user click is inside of the current matplotlib plot + # which is given by self.m.ax + if (event.button == 1 + and (event.xdata != None and event.ydata != None) + and self.m.ax == event.inaxes): + newx = int(event.xdata) + newy = int(event.ydata) + # get the ID of the selected cell + selectedcell_ID = self.m.plotmask[newy,newx] + # binarize the existing mask and number ("label") each component + labeled_binarized_mask = skimage.measure.label(self.m.plotmask > 0) + # select the component pixels that corresponds to the selected point + flood_indices=(labeled_binarized_mask==labeled_binarized_mask[newy,newx]) + # set the mask pixels that correspond to the component to the cell ID + self.m.plotmask[flood_indices] = selectedcell_ID + + # updates the plot to see the modification. + self.m.updatedata() + + self.Enable(self.button_mergewithneighbors) + self.button_mergewithneighbors.setChecked(False) + self.m.ShowCellNumbers() + self.SaveMask() + self.ClearStatusBar() + + # ----------------------------------------------------------------------------- # BUTTON ENABLE / DISABLE diff --git a/init/InitButtons.py b/init/InitButtons.py index f4d013b..3dff210 100644 --- a/init/InitButtons.py +++ b/init/InitButtons.py @@ -161,7 +161,7 @@ def Init(parent): # parent.button_changecellvalue.setStatusTip('') parent.button_changecellvalue.setStatusTip('Change ID value of one cell. Use left click to select one cell and enter a new ID value.') - # EXCHANGE CELL VALUES + # SPLIT CELLS parent.button_split.toggle() parent.button_split.setCheckable(True) parent.button_split.setEnabled(True) @@ -171,6 +171,16 @@ def Init(parent): parent.button_split.setToolTip("Shortcut: X") parent.button_split.setStatusTip('Split a selected cell into two. First left-click to select the cell, then draw a polygon around an area to split it off.') + # MERGE CELLS + parent.button_mergewithneighbors.toggle() + parent.button_mergewithneighbors.setCheckable(True) + parent.button_mergewithneighbors.setEnabled(True) + parent.button_mergewithneighbors.clicked.connect(parent.MergeWithNeighbors) + parent.button_mergewithneighbors.setMaximumWidth(150) + parent.button_mergewithneighbors.setShortcut("F") + parent.button_mergewithneighbors.setToolTip("Shortcut: F") + parent.button_mergewithneighbors.setStatusTip('Merge a cell with its immediate neighbors. Left-click to select the cell or right-click to abort.') + # MAKE THE CELL Correspondence parent.button_cellcorrespondence.setEnabled(False) parent.button_cellcorrespondence.setCheckable(True) diff --git a/init/InitLayout.py b/init/InitLayout.py index 18af51f..06e73da 100644 --- a/init/InitLayout.py +++ b/init/InitLayout.py @@ -44,6 +44,7 @@ def Init(parent): hboxcorrectionsbuttons.addWidget(parent.button_add_region) hboxcorrectionsbuttons.addWidget(parent.button_newcell) hboxcorrectionsbuttons.addWidget(parent.button_split) + hboxcorrectionsbuttons.addWidget(parent.button_mergewithneighbors) hboxcorrectionsbuttons.addWidget(parent.button_drawmouse) hboxcorrectionsbuttons.addWidget(parent.button_eraser) hboxcorrectionsbuttons.addWidget(parent.label_brushsize) -- GitLab