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) 50 layout.addWidget(self.button2) 51 52 # Add the widgets to the layout. 53 self.setLayout(layout) 54 55 def _write_pp(self, segmentation): 56 layer_name = self.output_layer_param.text() 57 if layer_name in self.viewer.layers: 58 self.viewer.layers[layer_name].data = segmentation 59 else: 60 self.viewer.add_labels(segmentation, name=layer_name) 61 62 def _conditions_met(self): 63 if self.output_layer_param.text() == "": 64 show_info("Please choose an output layer.") 65 return False 66 return True 67 68 def _get_segmentation_and_mask(self): 69 segmentation = self._get_layer_selector_data(self.segmentation_selector_name).copy() 70 mask = self._get_layer_selector_data(self.mask_selector_name) 71 mask_id = self.mask_id_param.value() 72 if mask_id != 0: 73 mask = (mask == mask_id).astype(mask.dtype) 74 return segmentation, mask 75 76 def on_filter(self): 77 if not self._conditions_met(): 78 return 79 segmentation, mask = self._get_segmentation_and_mask() 80 props = regionprops(segmentation, mask) 81 filter_ids = [prop.label for prop in props if prop.max_intensity == 0] 82 segmentation[np.isin(segmentation, filter_ids)] = 0 83 self._write_pp(segmentation) 84 85 def on_intersect(self): 86 if not self._conditions_met(): 87 return 88 segmentation, mask = self._get_segmentation_and_mask() 89 boundary = find_boundaries(mask) 90 segmentation = np.logical_and(segmentation > 0, boundary).astype(segmentation.dtype) 91 self._write_pp(segmentation)
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) 51 layout.addWidget(self.button2) 52 53 # Add the widgets to the layout. 54 self.setLayout(layout) 55 56 def _write_pp(self, segmentation): 57 layer_name = self.output_layer_param.text() 58 if layer_name in self.viewer.layers: 59 self.viewer.layers[layer_name].data = segmentation 60 else: 61 self.viewer.add_labels(segmentation, name=layer_name) 62 63 def _conditions_met(self): 64 if self.output_layer_param.text() == "": 65 show_info("Please choose an output layer.") 66 return False 67 return True 68 69 def _get_segmentation_and_mask(self): 70 segmentation = self._get_layer_selector_data(self.segmentation_selector_name).copy() 71 mask = self._get_layer_selector_data(self.mask_selector_name) 72 mask_id = self.mask_id_param.value() 73 if mask_id != 0: 74 mask = (mask == mask_id).astype(mask.dtype) 75 return segmentation, mask 76 77 def on_filter(self): 78 if not self._conditions_met(): 79 return 80 segmentation, mask = self._get_segmentation_and_mask() 81 props = regionprops(segmentation, mask) 82 filter_ids = [prop.label for prop in props if prop.max_intensity == 0] 83 segmentation[np.isin(segmentation, filter_ids)] = 0 84 self._write_pp(segmentation) 85 86 def on_intersect(self): 87 if not self._conditions_met(): 88 return 89 segmentation, mask = self._get_segmentation_and_mask() 90 boundary = find_boundaries(mask) 91 segmentation = np.logical_and(segmentation > 0, boundary).astype(segmentation.dtype) 92 self._write_pp(segmentation)
QWidget(parent: typing.Optional[QWidget] = None, flags: Union[Qt.WindowFlags, Qt.WindowType] = Qt.WindowFlags())
def
on_filter(self):
77 def on_filter(self): 78 if not self._conditions_met(): 79 return 80 segmentation, mask = self._get_segmentation_and_mask() 81 props = regionprops(segmentation, mask) 82 filter_ids = [prop.label for prop in props if prop.max_intensity == 0] 83 segmentation[np.isin(segmentation, filter_ids)] = 0 84 self._write_pp(segmentation)