synapse_net.tools.postprocessing_widget

  1import napari
  2import napari.layers
  3import napari.viewer
  4
  5import numpy as np
  6
  7from napari.utils.notifications import show_info
  8from qtpy.QtWidgets import QVBoxLayout, QPushButton
  9from skimage.measure import regionprops
 10from skimage.segmentation import find_boundaries
 11
 12from .base_widget import BaseWidget
 13
 14
 15class PostprocessingWidget(BaseWidget):
 16    def __init__(self):
 17        super().__init__()
 18
 19        self.viewer = napari.current_viewer()
 20        layout = QVBoxLayout()
 21
 22        # Create the dropdown to select the segmentation to post-process.
 23        self.segmentation_selector_name = "Segmentation"
 24        self.segmentation_selector_widget = self._create_layer_selector(
 25            self.segmentation_selector_name, layer_type="Labels"
 26        )
 27        layout.addWidget(self.segmentation_selector_widget)
 28
 29        # Create dropdown to select the mask for filtering / intersection.
 30        self.mask_selector_name = "Mask"
 31        self.mask_selector_widget = self._create_layer_selector(self.mask_selector_name, layer_type="Labels")
 32        layout.addWidget(self.mask_selector_widget)
 33
 34        # Create input for label id in the mask.
 35        self.mask_id_param, _ = self._add_int_param(
 36            "mask_id", 0, min_val=0, max_val=1000, layout=layout, title="Mask ID"
 37        )
 38
 39        # Create text field to choose the name of the output layer.
 40        self.output_layer_param, _ = self._add_string_param("output_layer", "", title="Output Layer", layout=layout)
 41
 42        # First postprocessing option: Filter with mask.
 43        self.button1 = QPushButton("Filter")
 44        self.button1.clicked.connect(self.on_filter)
 45        layout.addWidget(self.button1)
 46
 47        # Second postprocessing option: intersect with boundary of the mask.
 48        self.button2 = QPushButton("Intersect with Boundary")
 49        self.button2.clicked.connect(self.on_intersect_boundary)
 50        layout.addWidget(self.button2)
 51
 52        # Third postprocessing option: intersect with the mask.
 53        self.button3 = QPushButton("Intersect")
 54        self.button3.clicked.connect(self.on_intersect)
 55        layout.addWidget(self.button3)
 56
 57        # Add the widgets to the layout.
 58        self.setLayout(layout)
 59
 60    def _write_pp(self, segmentation):
 61        layer_name = self.output_layer_param.text()
 62        if layer_name in self.viewer.layers:
 63            self.viewer.layers[layer_name].data = segmentation
 64        else:
 65            self.viewer.add_labels(segmentation, name=layer_name)
 66
 67    def _conditions_met(self):
 68        if self.output_layer_param.text() == "":
 69            show_info("Please choose an output layer.")
 70            return False
 71        return True
 72
 73    def _get_segmentation_and_mask(self):
 74        segmentation = self._get_layer_selector_data(self.segmentation_selector_name).copy()
 75        mask = self._get_layer_selector_data(self.mask_selector_name)
 76        mask_id = self.mask_id_param.value()
 77        if mask_id != 0:
 78            mask = (mask == mask_id).astype(mask.dtype)
 79        return segmentation, mask
 80
 81    def on_filter(self):
 82        if not self._conditions_met():
 83            return
 84        segmentation, mask = self._get_segmentation_and_mask()
 85        props = regionprops(segmentation, mask)
 86        filter_ids = [prop.label for prop in props if prop.max_intensity == 0]
 87        segmentation[np.isin(segmentation, filter_ids)] = 0
 88        self._write_pp(segmentation)
 89
 90    def on_intersect_boundary(self):
 91        if not self._conditions_met():
 92            return
 93        segmentation, mask = self._get_segmentation_and_mask()
 94        boundary = find_boundaries(mask)
 95        segmentation = np.logical_and(segmentation > 0, boundary).astype(segmentation.dtype)
 96        self._write_pp(segmentation)
 97
 98    def on_intersect(self):
 99        if not self._conditions_met():
100            return
101        segmentation, mask = self._get_segmentation_and_mask()
102        segmentation = np.logical_and(segmentation > 0, mask > 0).astype(segmentation.dtype)
103        self._write_pp(segmentation)
class PostprocessingWidget(synapse_net.tools.base_widget.BaseWidget):
 16class PostprocessingWidget(BaseWidget):
 17    def __init__(self):
 18        super().__init__()
 19
 20        self.viewer = napari.current_viewer()
 21        layout = QVBoxLayout()
 22
 23        # Create the dropdown to select the segmentation to post-process.
 24        self.segmentation_selector_name = "Segmentation"
 25        self.segmentation_selector_widget = self._create_layer_selector(
 26            self.segmentation_selector_name, layer_type="Labels"
 27        )
 28        layout.addWidget(self.segmentation_selector_widget)
 29
 30        # Create dropdown to select the mask for filtering / intersection.
 31        self.mask_selector_name = "Mask"
 32        self.mask_selector_widget = self._create_layer_selector(self.mask_selector_name, layer_type="Labels")
 33        layout.addWidget(self.mask_selector_widget)
 34
 35        # Create input for label id in the mask.
 36        self.mask_id_param, _ = self._add_int_param(
 37            "mask_id", 0, min_val=0, max_val=1000, layout=layout, title="Mask ID"
 38        )
 39
 40        # Create text field to choose the name of the output layer.
 41        self.output_layer_param, _ = self._add_string_param("output_layer", "", title="Output Layer", layout=layout)
 42
 43        # First postprocessing option: Filter with mask.
 44        self.button1 = QPushButton("Filter")
 45        self.button1.clicked.connect(self.on_filter)
 46        layout.addWidget(self.button1)
 47
 48        # Second postprocessing option: intersect with boundary of the mask.
 49        self.button2 = QPushButton("Intersect with Boundary")
 50        self.button2.clicked.connect(self.on_intersect_boundary)
 51        layout.addWidget(self.button2)
 52
 53        # Third postprocessing option: intersect with the mask.
 54        self.button3 = QPushButton("Intersect")
 55        self.button3.clicked.connect(self.on_intersect)
 56        layout.addWidget(self.button3)
 57
 58        # Add the widgets to the layout.
 59        self.setLayout(layout)
 60
 61    def _write_pp(self, segmentation):
 62        layer_name = self.output_layer_param.text()
 63        if layer_name in self.viewer.layers:
 64            self.viewer.layers[layer_name].data = segmentation
 65        else:
 66            self.viewer.add_labels(segmentation, name=layer_name)
 67
 68    def _conditions_met(self):
 69        if self.output_layer_param.text() == "":
 70            show_info("Please choose an output layer.")
 71            return False
 72        return True
 73
 74    def _get_segmentation_and_mask(self):
 75        segmentation = self._get_layer_selector_data(self.segmentation_selector_name).copy()
 76        mask = self._get_layer_selector_data(self.mask_selector_name)
 77        mask_id = self.mask_id_param.value()
 78        if mask_id != 0:
 79            mask = (mask == mask_id).astype(mask.dtype)
 80        return segmentation, mask
 81
 82    def on_filter(self):
 83        if not self._conditions_met():
 84            return
 85        segmentation, mask = self._get_segmentation_and_mask()
 86        props = regionprops(segmentation, mask)
 87        filter_ids = [prop.label for prop in props if prop.max_intensity == 0]
 88        segmentation[np.isin(segmentation, filter_ids)] = 0
 89        self._write_pp(segmentation)
 90
 91    def on_intersect_boundary(self):
 92        if not self._conditions_met():
 93            return
 94        segmentation, mask = self._get_segmentation_and_mask()
 95        boundary = find_boundaries(mask)
 96        segmentation = np.logical_and(segmentation > 0, boundary).astype(segmentation.dtype)
 97        self._write_pp(segmentation)
 98
 99    def on_intersect(self):
100        if not self._conditions_met():
101            return
102        segmentation, mask = self._get_segmentation_and_mask()
103        segmentation = np.logical_and(segmentation > 0, mask > 0).astype(segmentation.dtype)
104        self._write_pp(segmentation)

QWidget(parent: Optional[QWidget] = None, flags: Union[Qt.WindowFlags, Qt.WindowType] = Qt.WindowFlags())

viewer
segmentation_selector_name
segmentation_selector_widget
mask_selector_name
mask_selector_widget
button1
button2
button3
def on_filter(self):
82    def on_filter(self):
83        if not self._conditions_met():
84            return
85        segmentation, mask = self._get_segmentation_and_mask()
86        props = regionprops(segmentation, mask)
87        filter_ids = [prop.label for prop in props if prop.max_intensity == 0]
88        segmentation[np.isin(segmentation, filter_ids)] = 0
89        self._write_pp(segmentation)
def on_intersect_boundary(self):
91    def on_intersect_boundary(self):
92        if not self._conditions_met():
93            return
94        segmentation, mask = self._get_segmentation_and_mask()
95        boundary = find_boundaries(mask)
96        segmentation = np.logical_and(segmentation > 0, boundary).astype(segmentation.dtype)
97        self._write_pp(segmentation)
def on_intersect(self):
 99    def on_intersect(self):
100        if not self._conditions_met():
101            return
102        segmentation, mask = self._get_segmentation_and_mask()
103        segmentation = np.logical_and(segmentation > 0, mask > 0).astype(segmentation.dtype)
104        self._write_pp(segmentation)