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)
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())
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)