@@ -17,12 +17,11 @@ def __init__(self):
17
17
self .viewer = napari .current_viewer ()
18
18
layout = QVBoxLayout ()
19
19
20
- self .selectors = {}
21
20
self .image_selector_name1 = "Segmentation 1"
22
21
self .image_selector_name2 = "Segmentation 2"
23
22
# Create the image selection dropdown
24
- self .segmentation1_selector_widget = self .create_image_selector ( selector_name = self .image_selector_name1 )
25
- self .segmentation2_selector_widget = self .create_image_selector ( selector_name = self .image_selector_name2 )
23
+ self .segmentation1_selector_widget = self ._create_layer_selector ( self .image_selector_name1 , layer_type = "Labels" )
24
+ self .segmentation2_selector_widget = self ._create_layer_selector ( self .image_selector_name2 , layer_type = "Labels" )
26
25
27
26
# create save path
28
27
self .settings = self ._create_settings_widget ()
@@ -45,17 +44,9 @@ def __init__(self):
45
44
46
45
self .setLayout (layout )
47
46
48
- def get_selected_layer_data (self , selector_name ):
49
- """Return the data for the layer currently selected in a given selector."""
50
- if selector_name in self .selectors :
51
- selected_layer_name = self .selectors [selector_name ].currentText ()
52
- if selected_layer_name in self .viewer .layers :
53
- return self .viewer .layers [selected_layer_name ].data
54
- return None # Return None if layer not found
55
-
56
47
def on_measure_segmentation_to_object (self ):
57
- segmentation1_data = self .get_selected_layer_data (self .image_selector_name1 )
58
- segmentation2_data = self .get_selected_layer_data (self .image_selector_name2 )
48
+ segmentation1_data = self ._get_layer_selector_data (self .image_selector_name1 )
49
+ segmentation2_data = self ._get_layer_selector_data (self .image_selector_name2 )
59
50
if segmentation1_data is None or segmentation2_data is None :
60
51
show_info ("Please choose both segmentation layers." )
61
52
return
@@ -64,144 +55,79 @@ def on_measure_segmentation_to_object(self):
64
55
(distances ,
65
56
endpoints1 ,
66
57
endpoints2 ,
67
- seg_ids ,
68
- object_ids ) = distance_measurements .measure_segmentation_to_object_distances (
58
+ seg_ids ) = distance_measurements .measure_segmentation_to_object_distances (
69
59
segmentation = segmentation1_data ,
70
60
segmented_object = segmentation2_data ,
71
61
distance_type = "boundary" ,
72
62
# save_path=self.save_path
73
63
)
74
- if self .save_path is not None :
75
- file_path = save_to_csv (self .save_path , data = (distances , endpoints1 , endpoints2 , seg_ids , object_ids ))
64
+ if self .save_path .text () != "" :
65
+ # save to csv
66
+ header = "distances endpoints1 endpoints2 seg_ids"
67
+ header_list = header .split (" " )
68
+ file_path = save_to_csv (
69
+ self .save_path .text (),
70
+ data = (distances , endpoints1 , endpoints2 , seg_ids ),
71
+ header = header_list
72
+ )
76
73
show_info (f"Measurements saved to { file_path } " )
74
+ lines , properties = distance_measurements .create_object_distance_lines (
75
+ distances = distances ,
76
+ endpoints1 = endpoints1 ,
77
+ endpoints2 = endpoints2 ,
78
+ seg_ids = seg_ids
79
+ )
77
80
78
- show_info ("Not implemented yet." )
81
+ # Add the lines layer
82
+ self .viewer .add_shapes (
83
+ lines ,
84
+ name = "Distance Lines" ,
85
+ shape_type = "line" , # Specify the shape type as 'line'
86
+ edge_width = 2 ,
87
+ edge_color = "red" ,
88
+ blending = "additive" , # Use 'additive' for blending if needed
89
+ )
90
+ if self .save_path .text () != "" :
91
+ show_info (f"Added distance lines and saved file to { file_path } ." )
92
+ else :
93
+ show_info ("Added distance lines." )
79
94
return
80
95
81
96
def on_measure_pairwise (self ):
82
97
if self .image is None :
83
98
show_info ("Please choose a segmentation." )
84
99
return
85
- if self .save_path is None :
100
+ if self .save_path . value () is None :
86
101
show_info ("Please choose a save path." )
87
102
return
88
- # get segmentation
89
- segmentation = self .image
90
- # run measurements
91
103
show_info ("Not implemented yet." )
92
104
return
93
- distance_measurements .measure_pairwise_object_distances (
94
- segmentation = segmentation , distance_type = "boundary" ,
95
- save_path = self .save_path
96
- )
97
- lines , properties = distance_measurements .create_distance_lines (
98
- measurement_path = self .save_path
99
- )
100
-
101
- # Add the lines layer
102
- self .viewer .add_lines (
103
- lines , name = "Distance Lines" , visible = True , edge_width = 2 , edge_color = "red" , edge_blend = "additive"
104
- )
105
-
106
- # layer_kwargs = {"colormap": "inferno", "blending": "additive"}
107
- # return segmentation, layer_kwargs
108
-
109
- def create_image_selector (self , selector_name ):
110
- attribute_dict = {}
111
- viewer = self .viewer
112
- """Create an image selector widget for a specific layer attribute."""
113
- selector_widget = QWidget ()
114
- image_selector = QComboBox ()
115
- title_label = QLabel (f"Select Layer for { selector_name } :" )
116
-
117
- # Populate initial options
118
- self .update_selector (viewer , image_selector )
119
-
120
- # Connect selection change to update image data in attribute_dict
121
- image_selector .currentIndexChanged .connect (
122
- lambda : self .update_image_data (viewer , image_selector , attribute_dict , selector_name )
123
- )
124
-
125
- # Update selector on layer events
126
- viewer .layers .events .inserted .connect (lambda event : self .update_selector (viewer , image_selector ))
127
- viewer .layers .events .removed .connect (lambda event : self .update_selector (viewer , image_selector ))
128
-
129
- # Store this combo box in the selectors dictionary
130
- self .selectors [selector_name ] = image_selector
131
-
132
- # Set up layout
133
- layout = QVBoxLayout ()
134
- layout .addWidget (title_label )
135
- layout .addWidget (image_selector )
136
- selector_widget .setLayout (layout )
137
-
138
- return selector_widget
139
-
140
- def update_selector (self , viewer , selector ):
141
- """Update a single selector with the current image layers in the viewer."""
142
- selector .clear ()
143
- image_layers = [layer .name for layer in viewer .layers ] # if isinstance(layer, napari.layers.Image)
144
- selector .addItems (image_layers )
145
-
146
- def update_image_data (self , viewer , selector , attribute_dict , attribute_name ):
147
- """Update the specified attribute in the attribute_dict with selected layer data."""
148
- selected_layer_name = selector .currentText ()
149
- if selected_layer_name in viewer .layers :
150
- attribute_dict [attribute_name ] = viewer .layers [selected_layer_name ].data
151
- else :
152
- attribute_dict [attribute_name ] = None # Reset if no valid selection
105
+ # distance_measurements.measure_pairwise_object_distances(
106
+ # segmentation=segmentation, distance_type="boundary",
107
+ # save_path=self.save_path
108
+ # )
109
+ # lines, properties = distance_measurements.create_distance_lines(
110
+ # measurement_path=self.save_path
111
+ # )
112
+
113
+ # # Add the lines layer
114
+ # self.viewer.add_lines(
115
+ # lines, name="Distance Lines", visible=True, edge_width=2, edge_color="red", edge_blend="additive"
116
+ # )
153
117
154
118
def _create_settings_widget (self ):
155
119
setting_values = QWidget ()
156
120
# setting_values.setToolTip(get_tooltip("embedding", "settings"))
157
121
setting_values .setLayout (QVBoxLayout ())
158
122
159
123
self .save_path , layout = self ._add_path_param (
160
- name = "Save Directory" , select_type = "directory" , value = None
124
+ name = "Save Directory" , select_type = "directory" , value = ""
161
125
)
162
126
setting_values .layout ().addLayout (layout )
163
127
164
128
settings = self ._make_collapsible (widget = setting_values , title = "Advanced Settings" )
165
129
return settings
166
130
167
- # def create_image_selector(self):
168
- # selector_widget = QWidget()
169
- # self.image_selector = QComboBox()
170
-
171
- # title_label = QLabel("Select Image Layer:")
172
-
173
- # # Populate initial options
174
- # self.update_image_selector()
175
-
176
- # # Connect selection change to update self.image
177
- # self.image_selector.currentIndexChanged.connect(self.update_image_data)
178
-
179
- # # Connect to Napari layer events to update the list
180
- # self.viewer.layers.events.inserted.connect(self.update_image_selector)
181
- # self.viewer.layers.events.removed.connect(self.update_image_selector)
182
-
183
- # layout = QVBoxLayout()
184
- # layout.addWidget(title_label)
185
- # layout.addWidget(self.image_selector)
186
- # selector_widget.setLayout(layout)
187
- # return selector_widget
188
-
189
- # def update_image_selector(self, event=None):
190
- # """Update dropdown options with current image layers in the viewer."""
191
- # self.image_selector.clear()
192
-
193
- # # Add each image layer's name to the dropdown
194
- # image_layers = [layer.name for layer in self.viewer.layers if isinstance(layer, napari.layers.Image)]
195
- # self.image_selector.addItems(image_layers)
196
-
197
- # def update_image_data(self):
198
- # """Update the self.image attribute with data from the selected layer."""
199
- # selected_layer_name = self.image_selector.currentText()
200
- # if selected_layer_name in self.viewer.layers:
201
- # self.image = self.viewer.layers[selected_layer_name].data
202
- # else:
203
- # self.image = None # Reset if no valid selection
204
-
205
131
206
132
def get_distance_measure_widget ():
207
133
return DistanceMeasureWidget ()
0 commit comments