epicure.displaying
EpiCure display options
Handles the Display panel of EpiCure.
Proposes some vizualisation options that could be convenient for some users.
For example, handles the option to add a grid in the background for spatial guidance or to show the skeleton of the segmentation.
1""" 2 **EpiCure display options** 3 4 Handles the `Display` panel of EpiCure. 5 Proposes some vizualisation options that could be convenient for some users. 6 For example, handles the option to add a grid in the background for spatial guidance or to show the skeleton of the segmentation. 7""" 8 9import numpy as np 10from math import ceil 11from qtpy.QtWidgets import QHBoxLayout, QVBoxLayout, QWidget, QComboBox 12from qtpy.QtCore import Qt 13from magicgui.widgets import TextEdit 14import epicure.Utils as ut 15import epicure.epiwidgets as wid 16 17 18class Displaying(QWidget): 19 """ Propose some visualization options """ 20 21 def __init__(self, napari_viewer, epic): 22 """ Create displaying widget instance """ 23 super().__init__() 24 self.viewer = napari_viewer 25 self.epicure = epic 26 self.seglayer = self.viewer.layers["Segmentation"] 27 self.gmode = 0 ## view only movie mode on/off 28 self.dmode = 0 ## view with light segmentation on/off 29 self.grid_color = [0.6, 0.7, 0.7, 0.7] ## default grid color 30 self.shapelayer_name = "ROIs" 31 32 layout = QVBoxLayout() 33 34 ## Show a text window with some summary of the file 35 show_summary = wid.add_button( "Show summary", self.show_summary_window, "Pops-up a summary of the movie and segmentation informations" ) 36 layout.addWidget(show_summary) 37 38 ## Draw and measure length of a line 39 measure_line = wid.add_button( "Measure length", self.measure_line_length, "Draw a line and measure its length" ) 40 layout.addWidget(measure_line) 41 42 ## Option show segmentation skeleton 43 self.show_skeleton = wid.add_check( "Show segmentation skeleton", False, self.show_skeleton_segmentation, "Add a layer with the segmentation skeleton (not automatically updated)" ) 44 layout.addWidget(self.show_skeleton) 45 46 ## Option to show the movie and seg side by side 47 show_sides = QHBoxLayout() 48 self.show_side = wid.add_check( "Side by side view", False, self.show_side_side, "View the movie and the other layers side by side" ) 49 show_sides.addWidget( self.show_side ) 50 self.directions = QComboBox() 51 self.directions.addItem( "Horizontal" ) 52 self.directions.addItem( "Vertical" ) 53 show_sides.addWidget( self.directions ) 54 self.directions.currentIndexChanged.connect( self.show_side_side ) 55 layout.addLayout( show_sides ) 56 57 ## Option show shifted segmentation 58 self.show_shifted = wid.add_check( "Overlay previous segmentation", False, self.show_shifted_segmentation, "Overlay the (frame-1) segmentation on the current segmentation") 59 layout.addWidget(self.show_shifted) 60 61 ## Option show shifted movie (previous or next) 62 show_prevmovie_line = QHBoxLayout() 63 self.show_previous_movie = wid.add_check( "Overlay previous movie", False, self.show_shifted_previous_movie, "Overlay the (frame-1) of the movie on the current movie" ) 64 layout.addWidget(self.show_previous_movie) 65 self.show_next_movie = wid.add_check( "Overlay next movie", False, self.show_shifted_next_movie, "Overlay (frame+1) of the movie on the current frame" ) 66 layout.addWidget(self.show_next_movie) 67 68 ## Option create/show grid 69 grid_line, self.show_grid_options, self.group_grid = wid.checkgroup_help( "Grid options", True, "Show/hide subpanel to control grid view", "Display#grid-options", self.epicure.display_colors, groupnb="group" ) 70 self.grid_parameters() 71 layout.addWidget(self.show_grid_options) 72 layout.addWidget(self.group_grid) 73 74 self.save_contrast = wid.add_check("Save Movie current contrast", True, descr="When saving current settings, save also current contrast of the Movie layer" ) 75 save_pref = wid.add_button( "Set current settings as default", self.save_current_display, "Save the current settings so that EpiCure will open in the same state next time" ) 76 layout.addWidget(save_pref) 77 78 self.add_display_overlay_message() 79 self.key_bindings() ## activate shortcuts for display options 80 self.setLayout(layout) 81 ut.set_active_layer( self.viewer, "Segmentation" ) 82 83 ### set current display as defaut 84 def save_current_display( self ): 85 """ Set current display parameters as defaut display """ 86 self.epicure.update_settings() 87 self.epicure.pref.save() 88 89 def get_current_settings( self ): 90 """ Returns current display settings """ 91 disp = {} 92 disp["Layers"] = {} 93 for layer in self.viewer.layers: 94 disp["Layers"][layer.name] = layer.visible 95 disp["Show Grid"] = self.show_grid_options.isChecked() 96 disp["Grid nrows"] = self.nrows.text() 97 disp["Grid ncols"] = self.ncols.text() 98 disp["Grid width"] = self.gwidth.text() 99 disp["Grid color"] = self.grid_color 100 disp["Show side on"] = self.show_side.isChecked() 101 disp["Side direction"] = self.directions.currentText() 102 if "EpicGrid" in self.viewer.layers: 103 disp["Grid text"] = self.viewer.layers["EpicGrid"].text.visible 104 disp["Grid color"] = self.viewer.layers["EpicGrid"].edge_color[0] 105 return disp 106 107 def apply_settings( self, settings ): 108 """ Set current display to prefered settings """ 109 add_grid = False 110 show_text = False 111 ## read the settings and apply them 112 for setty, val in settings.items(): 113 if setty == "Layers": 114 for layname, layvis in val.items(): 115 if layname in self.viewer.layers: 116 self.viewer.layers[layname].visible = layvis 117 else: 118 if layname == "EpicGrid": 119 add_grid = layvis 120 continue 121 if setty == "Show Grid": 122 self.show_grid_options.setChecked( val ) 123 continue 124 if setty == "Grid nrows": 125 self.nrows.setText( val ) 126 continue 127 if setty == "Grid ncols": 128 self.ncols.setText( val ) 129 continue 130 if setty == "Grid width": 131 self.gwidth.setText( val ) 132 continue 133 if setty == "Grid text": 134 show_text = val 135 continue 136 if setty == "Grid color": 137 self.grid_color = val 138 continue 139 if setty == "Show side on": 140 self.show_side.setChecked( val ) 141 if setty == "Side direction": 142 self.directions.setCurrentText( val ) 143 144 ## if grid should be added, do it at the end when all values are updated 145 if add_grid: 146 self.add_grid() 147 self.viewer.layers["EpicGrid"].text.visible = show_text 148 149 150 151 ######### overlay message 152 def add_display_overlay_message(self): 153 """ Shortcut list for display options """ 154 disptext = "--- Display options --- \n" 155 sdisp = self.epicure.shortcuts["Display"] 156 disptext += ut.print_shortcuts( sdisp ) 157 self.epicure.overtext["Display"] = disptext 158 sinfo = self.epicure.shortcuts["Info"] 159 self.epicure.overtext["info"] = "---- Info options --- \n" 160 self.epicure.overtext["info"] += ut.print_shortcuts( sinfo ) 161 162 163 164 ################ Key binging for display options 165 def key_bindings(self): 166 sdisp = self.epicure.shortcuts["Display"] 167 sinfo = self.epicure.shortcuts["Info"] 168 169 @self.seglayer.bind_key( sdisp["vis. segmentation"]["key"], overwrite=True ) 170 def see_segmentlayer(seglayer): 171 seglayer.visible = not seglayer.visible 172 173 @self.seglayer.bind_key( sdisp["vis. movie"]["key"], overwrite=True ) 174 def see_movielayer(seglayer): 175 ut.inv_visibility(self.viewer, "Movie") 176 177 @self.seglayer.bind_key( sdisp["vis. event"]["key"], overwrite=True ) 178 def see_eventslayer(seglayer): 179 evlayer = self.viewer.layers["Events"] 180 evlayer.visible = not evlayer.visible 181 182 @self.epicure.seglayer.bind_key( sinfo["measure length"]["key"], overwrite=True ) 183 def measure_length(layer): 184 """ 185 Draw a line and measure its length 186 """ 187 self.measure_line_length( layer ) 188 189 @self.seglayer.bind_key( sdisp["skeleton"]["key"], overwrite=True ) 190 def show_skeleton(seglayer): 191 """ On/Off show skeleton """ 192 if self.show_skeleton.isChecked(): 193 self.show_skeleton.setChecked(False) 194 else: 195 self.show_skeleton.setChecked(True) 196 197 @self.seglayer.bind_key( sdisp["show side"]["key"], overwrite=True ) 198 def show_byside(seglayer): 199 self.show_side.setChecked( not self.show_side.isChecked() ) 200 self.show_side_side() 201 202 @self.seglayer.bind_key( sdisp["increase"]["key"], overwrite=True ) 203 def contour_increase(seglayer): 204 if seglayer is not None: 205 seglayer.contour = seglayer.contour + 1 206 207 @self.seglayer.bind_key( sdisp["decrease"]["key"], overwrite=True ) 208 def contour_decrease(seglayer): 209 if seglayer is not None: 210 if seglayer.contour > 0: 211 seglayer.contour = seglayer.contour - 1 212 213 @self.seglayer.bind_key( sdisp["only movie"]["key"], overwrite=True ) 214 def see_onlymovielayer(seglayer): 215 """ if in "g" mode, show only movie, else put back to previous views """ 216 if self.gmode == 0: 217 self.lay_view = [] 218 for lay in self.viewer.layers: 219 self.lay_view.append( (lay, lay.visible) ) 220 lay.visible = False 221 ut.inv_visibility(self.viewer, "Movie") 222 self.gmode = 1 223 else: 224 for lay, vis in self.lay_view: 225 lay.visible = vis 226 self.gmode = 0 227 228 @self.seglayer.bind_key( sdisp["light view"]["key"], overwrite=True ) 229 def segmentation_lightmode(seglayer): 230 """ if in "d" mode, show only movie and light segmentation, else put back to previous views """ 231 if self.dmode == 0: 232 self.light_view = [] 233 for lay in self.viewer.layers: 234 self.light_view.append( (lay, lay.visible) ) 235 lay.visible = False 236 ut.inv_visibility(self.viewer, "Movie") 237 ut.inv_visibility(self.viewer, "Segmentation") 238 self.unlight_contour = self.seglayer.contour 239 self.unlight_opacity = self.seglayer.opacity 240 self.seglayer.contour = 1 241 self.seglayer.opacity = 0.2 242 self.dmode = 1 243 else: 244 for lay, vis in self.light_view: 245 lay.visible = vis 246 self.seglayer.contour = self.unlight_contour 247 self.seglayer.opacity = self.unlight_opacity 248 self.dmode = 0 249 250 @self.seglayer.bind_key( sdisp["grid"]["key"], overwrite=True ) 251 def show_grid(seglayer): 252 """ show/hide the grid to have a repere in space """ 253 self.show_grid() 254 255 ### Info options 256 def measure_line_length(self, layer=None): 257 """ 258 Draw a line and measure its length 259 """ 260 self.old_mouse_drag, self.old_key_map = ut.clear_bindings( self.epicure.seglayer ) 261 ut.show_info("Draw line to measure.") 262 if self.shapelayer_name not in self.viewer.layers: 263 self.create_shapelayer() 264 shape_lay = self.viewer.layers[self.shapelayer_name] 265 shape_lay.mode = "add_line" 266 shape_lay.visible = True 267 ut.set_active_layer( self.viewer, self.shapelayer_name) 268 269 @shape_lay.mouse_drag_callbacks.append 270 def click(layer, event): 271 if (event.type == "mouse_press") and (len(event.modifiers)==0) and (event.button==1): 272 ## dragg click to draw line 273 start_pos = event.position 274 yield 275 while event.type == 'mouse_move': 276 #print( event.position) 277 yield 278 end_pos = event.position 279 self.draw_line(shape_lay, start_pos, end_pos) 280 self.end_measure_mode() 281 else: 282 self.end_measure_mode() 283 284 def end_measure_mode(self): 285 """ Finish measuring mode """ 286 if self.old_mouse_drag is not None: 287 if self.shapelayer_name in self.viewer.layers: 288 shape_lay = self.viewer.layers[self.shapelayer_name] 289 shape_lay.visible = False 290 ut.reactive_bindings( self.epicure.seglayer, self.old_mouse_drag, self.old_key_map ) 291 ut.show_info("End measure") 292 ut.set_active_layer( self.viewer, "Segmentation" ) 293 294 def draw_line( self, shape_lay, start_position, end_position ): 295 """ Draw a line in the shape layer """ 296 #shape_lay.data = np.array( [start_position, end_position] ) 297 #shape_lay.features = { "length": np.linalg.norm(np.array(end_position[1:3]) - np.array(start_position[1:3])) } 298 length = np.linalg.norm(np.array(end_position[1:3]) - np.array(start_position[1:3])) 299 ut.setOverlayText( self.viewer, "Length: "+str(round(length,1))+" µm" ) 300 #shape_lay.text.string = "length" 301 #shape_lay.text.visible = True 302 shape_lay.data = shape_lay.data[:-1] ## remove last line drawn 303 shape_lay.refresh() 304 305 306 def show_summary_window(self): 307 """ Show a text window with some infos """ 308 summwin = TextEdit() 309 summwin.name = "Epicure summary" 310 summwin.value = self.epicure.get_summary() 311 summwin.show() 312 313 ### Display options 314 def show_skeleton_segmentation(self): 315 """ Show/hide/update skeleton """ 316 if "Skeleton" in self.viewer.layers: 317 ut.remove_layer(self.viewer, "Skeleton") 318 if self.show_skeleton.isChecked(): 319 self.epicure.add_skeleton() 320 ut.set_active_layer( self.viewer, "Segmentation" ) 321 322 def show_side_side( self ): 323 """ Show the layers side by side """ 324 layout_grid = self.viewer.grid 325 if self.show_side.isChecked(): 326 stride = len( self.viewer.layers ) - 1 327 layout_grid.stride = stride 328 layout_grid.shape = (2,1) 329 if self.directions.currentText() == "Horizontal": 330 layout_grid.shape = (1,2) 331 layout_grid.enabled = True 332 else: 333 layout_grid.enabled = False 334 335 336 def show_shifted_segmentation(self): 337 """ Show/Hide temporally shifted segmentation on top of current one """ 338 if ("PrevSegmentation" in self.viewer.layers): 339 if (not self.show_shifted.isChecked()): 340 ut.remove_layer(self.viewer, "PrevSegmentation") 341 else: 342 lay = self.viewer.layers["PrevSegmentation"] 343 lay.refresh() 344 345 if ("PrevSegmentation" not in self.viewer.layers) and (self.show_shifted.isChecked()): 346 if self.epicure.nframes > 1: 347 layer = self.viewer.add_labels( self.seglayer.data, name="PrevSegmentation", blending="additive", opacity=0.4 ) 348 layer.contour = 2 349 layer.translate = [1, 0, 0] 350 self.seglayer.contour = 2 351 self.seglayer.opacity = 0.6 352 else: 353 ut.show_warning("Still image, cannot show previous frames") 354 355 ut.set_active_layer( self.viewer, "Segmentation" ) 356 357 def show_shifted_previous_movie(self): 358 """ Show/Hide temporally shifted movie previous frame on top of current one """ 359 self.show_shifted_movie("PrevMovie", "red", 1) 360 361 def show_shifted_next_movie(self): 362 """ Show/Hide temporally shifted movie next frame on top of current one """ 363 self.show_shifted_movie("NextMovie", "green", -1) 364 365 def show_shifted_movie(self, layname, color, translation): 366 """ Show/Hide temporally shifted movie on top of current one """ 367 if (layname in self.viewer.layers): 368 if (not self.show_previous_movie.isChecked()): 369 ut.remove_layer(self.viewer, layname) 370 else: 371 lay = self.viewer.layers[layname] 372 lay.refresh() 373 374 if (layname not in self.viewer.layers) and (self.show_previous_movie.isChecked()): 375 if self.epicure.nframes > 1: 376 movlay = self.viewer.layers["Movie"] 377 arr = movlay.data 378 if translation == -1: 379 arr = movlay.data[1:,] 380 layer = self.viewer.add_image( arr, name=layname, blending="additive", opacity=0.6, colormap=color ) 381 if translation == 1: 382 layer.translate = [translation, 0, 0] 383 layer.contrast_limits=self.epicure.quantiles() 384 layer.gamma=0.94 385 else: 386 ut.show_warning("Still image, cannot show previous frames") 387 388 ut.set_active_layer( self.viewer, "Segmentation" ) 389 390 #### Show/load a grid to have a repere in space 391 def grid_parameters(self): 392 """ Interface to get grid parameters """ 393 grid_layout = QVBoxLayout() 394 ## nrows 395 rows_line, self.nrows = wid.value_line( "Nb rows", "4", "Number of rows of the grid" ) 396 grid_layout.addLayout(rows_line) 397 ## ncols 398 cols_line, self.ncols = wid.value_line( "Nb columns:", "4", "Number of columns in the grid" ) 399 grid_layout.addLayout(cols_line) 400 ## grid edges width 401 width_line, self.gwidth = wid.value_line( "Grid width:", "3", "Width of the grid displayed lines/columns" ) 402 grid_layout.addLayout(width_line) 403 ## go for grid 404 btn_add_grid = wid.add_button( "Add grid", self.add_grid, "Add a grid overlay to the main view" ) 405 grid_layout.addWidget(btn_add_grid) 406 self.group_grid.setLayout(grid_layout) 407 408 def add_grid(self): 409 """ Create/Load a new grid and add it """ 410 ut.remove_layer(self.viewer, "EpicGrid") 411 imshape = self.epicure.imgshape2D 412 if imshape is None: 413 ut.show_error("Load the image first") 414 return 415 nrows = int(self.nrows.text()) 416 ncols = int(self.ncols.text()) 417 wid = ceil(imshape[0]/nrows) 418 hei = ceil(imshape[1]/ncols) 419 rects = [] 420 rects_names = [] 421 gwidth = int(self.gwidth.text()) 422 for x in range(nrows): 423 for y in range(ncols): 424 rect = np.array([[x*wid, y*hei], [(x+1)*wid, (y+1)*hei]]) 425 rects.append(rect) 426 rects_names.append(chr(65+x)+"_"+str(y)) 427 self.viewer.add_shapes(rects, name="EpicGrid", text=rects_names, face_color=[1,0,0,0], edge_color=self.grid_color, edge_width=gwidth, opacity=0.7, scale=self.viewer.layers["Segmentation"].scale[1:]) 428 self.viewer.layers["EpicGrid"].text.visible = False 429 ut.set_active_layer( self.viewer, "Segmentation" ) 430 431 def show_grid(self): 432 """ Interface to create/load a grid for repere """ 433 if "EpicGrid" not in self.viewer.layers: 434 self.add_grid() 435 else: 436 gridlay = self.viewer.layers["EpicGrid"] 437 gridlay.visible = not gridlay.visible 438 gridlay.edge_color = self.grid_color
19class Displaying(QWidget): 20 """ Propose some visualization options """ 21 22 def __init__(self, napari_viewer, epic): 23 """ Create displaying widget instance """ 24 super().__init__() 25 self.viewer = napari_viewer 26 self.epicure = epic 27 self.seglayer = self.viewer.layers["Segmentation"] 28 self.gmode = 0 ## view only movie mode on/off 29 self.dmode = 0 ## view with light segmentation on/off 30 self.grid_color = [0.6, 0.7, 0.7, 0.7] ## default grid color 31 self.shapelayer_name = "ROIs" 32 33 layout = QVBoxLayout() 34 35 ## Show a text window with some summary of the file 36 show_summary = wid.add_button( "Show summary", self.show_summary_window, "Pops-up a summary of the movie and segmentation informations" ) 37 layout.addWidget(show_summary) 38 39 ## Draw and measure length of a line 40 measure_line = wid.add_button( "Measure length", self.measure_line_length, "Draw a line and measure its length" ) 41 layout.addWidget(measure_line) 42 43 ## Option show segmentation skeleton 44 self.show_skeleton = wid.add_check( "Show segmentation skeleton", False, self.show_skeleton_segmentation, "Add a layer with the segmentation skeleton (not automatically updated)" ) 45 layout.addWidget(self.show_skeleton) 46 47 ## Option to show the movie and seg side by side 48 show_sides = QHBoxLayout() 49 self.show_side = wid.add_check( "Side by side view", False, self.show_side_side, "View the movie and the other layers side by side" ) 50 show_sides.addWidget( self.show_side ) 51 self.directions = QComboBox() 52 self.directions.addItem( "Horizontal" ) 53 self.directions.addItem( "Vertical" ) 54 show_sides.addWidget( self.directions ) 55 self.directions.currentIndexChanged.connect( self.show_side_side ) 56 layout.addLayout( show_sides ) 57 58 ## Option show shifted segmentation 59 self.show_shifted = wid.add_check( "Overlay previous segmentation", False, self.show_shifted_segmentation, "Overlay the (frame-1) segmentation on the current segmentation") 60 layout.addWidget(self.show_shifted) 61 62 ## Option show shifted movie (previous or next) 63 show_prevmovie_line = QHBoxLayout() 64 self.show_previous_movie = wid.add_check( "Overlay previous movie", False, self.show_shifted_previous_movie, "Overlay the (frame-1) of the movie on the current movie" ) 65 layout.addWidget(self.show_previous_movie) 66 self.show_next_movie = wid.add_check( "Overlay next movie", False, self.show_shifted_next_movie, "Overlay (frame+1) of the movie on the current frame" ) 67 layout.addWidget(self.show_next_movie) 68 69 ## Option create/show grid 70 grid_line, self.show_grid_options, self.group_grid = wid.checkgroup_help( "Grid options", True, "Show/hide subpanel to control grid view", "Display#grid-options", self.epicure.display_colors, groupnb="group" ) 71 self.grid_parameters() 72 layout.addWidget(self.show_grid_options) 73 layout.addWidget(self.group_grid) 74 75 self.save_contrast = wid.add_check("Save Movie current contrast", True, descr="When saving current settings, save also current contrast of the Movie layer" ) 76 save_pref = wid.add_button( "Set current settings as default", self.save_current_display, "Save the current settings so that EpiCure will open in the same state next time" ) 77 layout.addWidget(save_pref) 78 79 self.add_display_overlay_message() 80 self.key_bindings() ## activate shortcuts for display options 81 self.setLayout(layout) 82 ut.set_active_layer( self.viewer, "Segmentation" ) 83 84 ### set current display as defaut 85 def save_current_display( self ): 86 """ Set current display parameters as defaut display """ 87 self.epicure.update_settings() 88 self.epicure.pref.save() 89 90 def get_current_settings( self ): 91 """ Returns current display settings """ 92 disp = {} 93 disp["Layers"] = {} 94 for layer in self.viewer.layers: 95 disp["Layers"][layer.name] = layer.visible 96 disp["Show Grid"] = self.show_grid_options.isChecked() 97 disp["Grid nrows"] = self.nrows.text() 98 disp["Grid ncols"] = self.ncols.text() 99 disp["Grid width"] = self.gwidth.text() 100 disp["Grid color"] = self.grid_color 101 disp["Show side on"] = self.show_side.isChecked() 102 disp["Side direction"] = self.directions.currentText() 103 if "EpicGrid" in self.viewer.layers: 104 disp["Grid text"] = self.viewer.layers["EpicGrid"].text.visible 105 disp["Grid color"] = self.viewer.layers["EpicGrid"].edge_color[0] 106 return disp 107 108 def apply_settings( self, settings ): 109 """ Set current display to prefered settings """ 110 add_grid = False 111 show_text = False 112 ## read the settings and apply them 113 for setty, val in settings.items(): 114 if setty == "Layers": 115 for layname, layvis in val.items(): 116 if layname in self.viewer.layers: 117 self.viewer.layers[layname].visible = layvis 118 else: 119 if layname == "EpicGrid": 120 add_grid = layvis 121 continue 122 if setty == "Show Grid": 123 self.show_grid_options.setChecked( val ) 124 continue 125 if setty == "Grid nrows": 126 self.nrows.setText( val ) 127 continue 128 if setty == "Grid ncols": 129 self.ncols.setText( val ) 130 continue 131 if setty == "Grid width": 132 self.gwidth.setText( val ) 133 continue 134 if setty == "Grid text": 135 show_text = val 136 continue 137 if setty == "Grid color": 138 self.grid_color = val 139 continue 140 if setty == "Show side on": 141 self.show_side.setChecked( val ) 142 if setty == "Side direction": 143 self.directions.setCurrentText( val ) 144 145 ## if grid should be added, do it at the end when all values are updated 146 if add_grid: 147 self.add_grid() 148 self.viewer.layers["EpicGrid"].text.visible = show_text 149 150 151 152 ######### overlay message 153 def add_display_overlay_message(self): 154 """ Shortcut list for display options """ 155 disptext = "--- Display options --- \n" 156 sdisp = self.epicure.shortcuts["Display"] 157 disptext += ut.print_shortcuts( sdisp ) 158 self.epicure.overtext["Display"] = disptext 159 sinfo = self.epicure.shortcuts["Info"] 160 self.epicure.overtext["info"] = "---- Info options --- \n" 161 self.epicure.overtext["info"] += ut.print_shortcuts( sinfo ) 162 163 164 165 ################ Key binging for display options 166 def key_bindings(self): 167 sdisp = self.epicure.shortcuts["Display"] 168 sinfo = self.epicure.shortcuts["Info"] 169 170 @self.seglayer.bind_key( sdisp["vis. segmentation"]["key"], overwrite=True ) 171 def see_segmentlayer(seglayer): 172 seglayer.visible = not seglayer.visible 173 174 @self.seglayer.bind_key( sdisp["vis. movie"]["key"], overwrite=True ) 175 def see_movielayer(seglayer): 176 ut.inv_visibility(self.viewer, "Movie") 177 178 @self.seglayer.bind_key( sdisp["vis. event"]["key"], overwrite=True ) 179 def see_eventslayer(seglayer): 180 evlayer = self.viewer.layers["Events"] 181 evlayer.visible = not evlayer.visible 182 183 @self.epicure.seglayer.bind_key( sinfo["measure length"]["key"], overwrite=True ) 184 def measure_length(layer): 185 """ 186 Draw a line and measure its length 187 """ 188 self.measure_line_length( layer ) 189 190 @self.seglayer.bind_key( sdisp["skeleton"]["key"], overwrite=True ) 191 def show_skeleton(seglayer): 192 """ On/Off show skeleton """ 193 if self.show_skeleton.isChecked(): 194 self.show_skeleton.setChecked(False) 195 else: 196 self.show_skeleton.setChecked(True) 197 198 @self.seglayer.bind_key( sdisp["show side"]["key"], overwrite=True ) 199 def show_byside(seglayer): 200 self.show_side.setChecked( not self.show_side.isChecked() ) 201 self.show_side_side() 202 203 @self.seglayer.bind_key( sdisp["increase"]["key"], overwrite=True ) 204 def contour_increase(seglayer): 205 if seglayer is not None: 206 seglayer.contour = seglayer.contour + 1 207 208 @self.seglayer.bind_key( sdisp["decrease"]["key"], overwrite=True ) 209 def contour_decrease(seglayer): 210 if seglayer is not None: 211 if seglayer.contour > 0: 212 seglayer.contour = seglayer.contour - 1 213 214 @self.seglayer.bind_key( sdisp["only movie"]["key"], overwrite=True ) 215 def see_onlymovielayer(seglayer): 216 """ if in "g" mode, show only movie, else put back to previous views """ 217 if self.gmode == 0: 218 self.lay_view = [] 219 for lay in self.viewer.layers: 220 self.lay_view.append( (lay, lay.visible) ) 221 lay.visible = False 222 ut.inv_visibility(self.viewer, "Movie") 223 self.gmode = 1 224 else: 225 for lay, vis in self.lay_view: 226 lay.visible = vis 227 self.gmode = 0 228 229 @self.seglayer.bind_key( sdisp["light view"]["key"], overwrite=True ) 230 def segmentation_lightmode(seglayer): 231 """ if in "d" mode, show only movie and light segmentation, else put back to previous views """ 232 if self.dmode == 0: 233 self.light_view = [] 234 for lay in self.viewer.layers: 235 self.light_view.append( (lay, lay.visible) ) 236 lay.visible = False 237 ut.inv_visibility(self.viewer, "Movie") 238 ut.inv_visibility(self.viewer, "Segmentation") 239 self.unlight_contour = self.seglayer.contour 240 self.unlight_opacity = self.seglayer.opacity 241 self.seglayer.contour = 1 242 self.seglayer.opacity = 0.2 243 self.dmode = 1 244 else: 245 for lay, vis in self.light_view: 246 lay.visible = vis 247 self.seglayer.contour = self.unlight_contour 248 self.seglayer.opacity = self.unlight_opacity 249 self.dmode = 0 250 251 @self.seglayer.bind_key( sdisp["grid"]["key"], overwrite=True ) 252 def show_grid(seglayer): 253 """ show/hide the grid to have a repere in space """ 254 self.show_grid() 255 256 ### Info options 257 def measure_line_length(self, layer=None): 258 """ 259 Draw a line and measure its length 260 """ 261 self.old_mouse_drag, self.old_key_map = ut.clear_bindings( self.epicure.seglayer ) 262 ut.show_info("Draw line to measure.") 263 if self.shapelayer_name not in self.viewer.layers: 264 self.create_shapelayer() 265 shape_lay = self.viewer.layers[self.shapelayer_name] 266 shape_lay.mode = "add_line" 267 shape_lay.visible = True 268 ut.set_active_layer( self.viewer, self.shapelayer_name) 269 270 @shape_lay.mouse_drag_callbacks.append 271 def click(layer, event): 272 if (event.type == "mouse_press") and (len(event.modifiers)==0) and (event.button==1): 273 ## dragg click to draw line 274 start_pos = event.position 275 yield 276 while event.type == 'mouse_move': 277 #print( event.position) 278 yield 279 end_pos = event.position 280 self.draw_line(shape_lay, start_pos, end_pos) 281 self.end_measure_mode() 282 else: 283 self.end_measure_mode() 284 285 def end_measure_mode(self): 286 """ Finish measuring mode """ 287 if self.old_mouse_drag is not None: 288 if self.shapelayer_name in self.viewer.layers: 289 shape_lay = self.viewer.layers[self.shapelayer_name] 290 shape_lay.visible = False 291 ut.reactive_bindings( self.epicure.seglayer, self.old_mouse_drag, self.old_key_map ) 292 ut.show_info("End measure") 293 ut.set_active_layer( self.viewer, "Segmentation" ) 294 295 def draw_line( self, shape_lay, start_position, end_position ): 296 """ Draw a line in the shape layer """ 297 #shape_lay.data = np.array( [start_position, end_position] ) 298 #shape_lay.features = { "length": np.linalg.norm(np.array(end_position[1:3]) - np.array(start_position[1:3])) } 299 length = np.linalg.norm(np.array(end_position[1:3]) - np.array(start_position[1:3])) 300 ut.setOverlayText( self.viewer, "Length: "+str(round(length,1))+" µm" ) 301 #shape_lay.text.string = "length" 302 #shape_lay.text.visible = True 303 shape_lay.data = shape_lay.data[:-1] ## remove last line drawn 304 shape_lay.refresh() 305 306 307 def show_summary_window(self): 308 """ Show a text window with some infos """ 309 summwin = TextEdit() 310 summwin.name = "Epicure summary" 311 summwin.value = self.epicure.get_summary() 312 summwin.show() 313 314 ### Display options 315 def show_skeleton_segmentation(self): 316 """ Show/hide/update skeleton """ 317 if "Skeleton" in self.viewer.layers: 318 ut.remove_layer(self.viewer, "Skeleton") 319 if self.show_skeleton.isChecked(): 320 self.epicure.add_skeleton() 321 ut.set_active_layer( self.viewer, "Segmentation" ) 322 323 def show_side_side( self ): 324 """ Show the layers side by side """ 325 layout_grid = self.viewer.grid 326 if self.show_side.isChecked(): 327 stride = len( self.viewer.layers ) - 1 328 layout_grid.stride = stride 329 layout_grid.shape = (2,1) 330 if self.directions.currentText() == "Horizontal": 331 layout_grid.shape = (1,2) 332 layout_grid.enabled = True 333 else: 334 layout_grid.enabled = False 335 336 337 def show_shifted_segmentation(self): 338 """ Show/Hide temporally shifted segmentation on top of current one """ 339 if ("PrevSegmentation" in self.viewer.layers): 340 if (not self.show_shifted.isChecked()): 341 ut.remove_layer(self.viewer, "PrevSegmentation") 342 else: 343 lay = self.viewer.layers["PrevSegmentation"] 344 lay.refresh() 345 346 if ("PrevSegmentation" not in self.viewer.layers) and (self.show_shifted.isChecked()): 347 if self.epicure.nframes > 1: 348 layer = self.viewer.add_labels( self.seglayer.data, name="PrevSegmentation", blending="additive", opacity=0.4 ) 349 layer.contour = 2 350 layer.translate = [1, 0, 0] 351 self.seglayer.contour = 2 352 self.seglayer.opacity = 0.6 353 else: 354 ut.show_warning("Still image, cannot show previous frames") 355 356 ut.set_active_layer( self.viewer, "Segmentation" ) 357 358 def show_shifted_previous_movie(self): 359 """ Show/Hide temporally shifted movie previous frame on top of current one """ 360 self.show_shifted_movie("PrevMovie", "red", 1) 361 362 def show_shifted_next_movie(self): 363 """ Show/Hide temporally shifted movie next frame on top of current one """ 364 self.show_shifted_movie("NextMovie", "green", -1) 365 366 def show_shifted_movie(self, layname, color, translation): 367 """ Show/Hide temporally shifted movie on top of current one """ 368 if (layname in self.viewer.layers): 369 if (not self.show_previous_movie.isChecked()): 370 ut.remove_layer(self.viewer, layname) 371 else: 372 lay = self.viewer.layers[layname] 373 lay.refresh() 374 375 if (layname not in self.viewer.layers) and (self.show_previous_movie.isChecked()): 376 if self.epicure.nframes > 1: 377 movlay = self.viewer.layers["Movie"] 378 arr = movlay.data 379 if translation == -1: 380 arr = movlay.data[1:,] 381 layer = self.viewer.add_image( arr, name=layname, blending="additive", opacity=0.6, colormap=color ) 382 if translation == 1: 383 layer.translate = [translation, 0, 0] 384 layer.contrast_limits=self.epicure.quantiles() 385 layer.gamma=0.94 386 else: 387 ut.show_warning("Still image, cannot show previous frames") 388 389 ut.set_active_layer( self.viewer, "Segmentation" ) 390 391 #### Show/load a grid to have a repere in space 392 def grid_parameters(self): 393 """ Interface to get grid parameters """ 394 grid_layout = QVBoxLayout() 395 ## nrows 396 rows_line, self.nrows = wid.value_line( "Nb rows", "4", "Number of rows of the grid" ) 397 grid_layout.addLayout(rows_line) 398 ## ncols 399 cols_line, self.ncols = wid.value_line( "Nb columns:", "4", "Number of columns in the grid" ) 400 grid_layout.addLayout(cols_line) 401 ## grid edges width 402 width_line, self.gwidth = wid.value_line( "Grid width:", "3", "Width of the grid displayed lines/columns" ) 403 grid_layout.addLayout(width_line) 404 ## go for grid 405 btn_add_grid = wid.add_button( "Add grid", self.add_grid, "Add a grid overlay to the main view" ) 406 grid_layout.addWidget(btn_add_grid) 407 self.group_grid.setLayout(grid_layout) 408 409 def add_grid(self): 410 """ Create/Load a new grid and add it """ 411 ut.remove_layer(self.viewer, "EpicGrid") 412 imshape = self.epicure.imgshape2D 413 if imshape is None: 414 ut.show_error("Load the image first") 415 return 416 nrows = int(self.nrows.text()) 417 ncols = int(self.ncols.text()) 418 wid = ceil(imshape[0]/nrows) 419 hei = ceil(imshape[1]/ncols) 420 rects = [] 421 rects_names = [] 422 gwidth = int(self.gwidth.text()) 423 for x in range(nrows): 424 for y in range(ncols): 425 rect = np.array([[x*wid, y*hei], [(x+1)*wid, (y+1)*hei]]) 426 rects.append(rect) 427 rects_names.append(chr(65+x)+"_"+str(y)) 428 self.viewer.add_shapes(rects, name="EpicGrid", text=rects_names, face_color=[1,0,0,0], edge_color=self.grid_color, edge_width=gwidth, opacity=0.7, scale=self.viewer.layers["Segmentation"].scale[1:]) 429 self.viewer.layers["EpicGrid"].text.visible = False 430 ut.set_active_layer( self.viewer, "Segmentation" ) 431 432 def show_grid(self): 433 """ Interface to create/load a grid for repere """ 434 if "EpicGrid" not in self.viewer.layers: 435 self.add_grid() 436 else: 437 gridlay = self.viewer.layers["EpicGrid"] 438 gridlay.visible = not gridlay.visible 439 gridlay.edge_color = self.grid_color
Propose some visualization options
22 def __init__(self, napari_viewer, epic): 23 """ Create displaying widget instance """ 24 super().__init__() 25 self.viewer = napari_viewer 26 self.epicure = epic 27 self.seglayer = self.viewer.layers["Segmentation"] 28 self.gmode = 0 ## view only movie mode on/off 29 self.dmode = 0 ## view with light segmentation on/off 30 self.grid_color = [0.6, 0.7, 0.7, 0.7] ## default grid color 31 self.shapelayer_name = "ROIs" 32 33 layout = QVBoxLayout() 34 35 ## Show a text window with some summary of the file 36 show_summary = wid.add_button( "Show summary", self.show_summary_window, "Pops-up a summary of the movie and segmentation informations" ) 37 layout.addWidget(show_summary) 38 39 ## Draw and measure length of a line 40 measure_line = wid.add_button( "Measure length", self.measure_line_length, "Draw a line and measure its length" ) 41 layout.addWidget(measure_line) 42 43 ## Option show segmentation skeleton 44 self.show_skeleton = wid.add_check( "Show segmentation skeleton", False, self.show_skeleton_segmentation, "Add a layer with the segmentation skeleton (not automatically updated)" ) 45 layout.addWidget(self.show_skeleton) 46 47 ## Option to show the movie and seg side by side 48 show_sides = QHBoxLayout() 49 self.show_side = wid.add_check( "Side by side view", False, self.show_side_side, "View the movie and the other layers side by side" ) 50 show_sides.addWidget( self.show_side ) 51 self.directions = QComboBox() 52 self.directions.addItem( "Horizontal" ) 53 self.directions.addItem( "Vertical" ) 54 show_sides.addWidget( self.directions ) 55 self.directions.currentIndexChanged.connect( self.show_side_side ) 56 layout.addLayout( show_sides ) 57 58 ## Option show shifted segmentation 59 self.show_shifted = wid.add_check( "Overlay previous segmentation", False, self.show_shifted_segmentation, "Overlay the (frame-1) segmentation on the current segmentation") 60 layout.addWidget(self.show_shifted) 61 62 ## Option show shifted movie (previous or next) 63 show_prevmovie_line = QHBoxLayout() 64 self.show_previous_movie = wid.add_check( "Overlay previous movie", False, self.show_shifted_previous_movie, "Overlay the (frame-1) of the movie on the current movie" ) 65 layout.addWidget(self.show_previous_movie) 66 self.show_next_movie = wid.add_check( "Overlay next movie", False, self.show_shifted_next_movie, "Overlay (frame+1) of the movie on the current frame" ) 67 layout.addWidget(self.show_next_movie) 68 69 ## Option create/show grid 70 grid_line, self.show_grid_options, self.group_grid = wid.checkgroup_help( "Grid options", True, "Show/hide subpanel to control grid view", "Display#grid-options", self.epicure.display_colors, groupnb="group" ) 71 self.grid_parameters() 72 layout.addWidget(self.show_grid_options) 73 layout.addWidget(self.group_grid) 74 75 self.save_contrast = wid.add_check("Save Movie current contrast", True, descr="When saving current settings, save also current contrast of the Movie layer" ) 76 save_pref = wid.add_button( "Set current settings as default", self.save_current_display, "Save the current settings so that EpiCure will open in the same state next time" ) 77 layout.addWidget(save_pref) 78 79 self.add_display_overlay_message() 80 self.key_bindings() ## activate shortcuts for display options 81 self.setLayout(layout) 82 ut.set_active_layer( self.viewer, "Segmentation" )
Create displaying widget instance
85 def save_current_display( self ): 86 """ Set current display parameters as defaut display """ 87 self.epicure.update_settings() 88 self.epicure.pref.save()
Set current display parameters as defaut display
90 def get_current_settings( self ): 91 """ Returns current display settings """ 92 disp = {} 93 disp["Layers"] = {} 94 for layer in self.viewer.layers: 95 disp["Layers"][layer.name] = layer.visible 96 disp["Show Grid"] = self.show_grid_options.isChecked() 97 disp["Grid nrows"] = self.nrows.text() 98 disp["Grid ncols"] = self.ncols.text() 99 disp["Grid width"] = self.gwidth.text() 100 disp["Grid color"] = self.grid_color 101 disp["Show side on"] = self.show_side.isChecked() 102 disp["Side direction"] = self.directions.currentText() 103 if "EpicGrid" in self.viewer.layers: 104 disp["Grid text"] = self.viewer.layers["EpicGrid"].text.visible 105 disp["Grid color"] = self.viewer.layers["EpicGrid"].edge_color[0] 106 return disp
Returns current display settings
108 def apply_settings( self, settings ): 109 """ Set current display to prefered settings """ 110 add_grid = False 111 show_text = False 112 ## read the settings and apply them 113 for setty, val in settings.items(): 114 if setty == "Layers": 115 for layname, layvis in val.items(): 116 if layname in self.viewer.layers: 117 self.viewer.layers[layname].visible = layvis 118 else: 119 if layname == "EpicGrid": 120 add_grid = layvis 121 continue 122 if setty == "Show Grid": 123 self.show_grid_options.setChecked( val ) 124 continue 125 if setty == "Grid nrows": 126 self.nrows.setText( val ) 127 continue 128 if setty == "Grid ncols": 129 self.ncols.setText( val ) 130 continue 131 if setty == "Grid width": 132 self.gwidth.setText( val ) 133 continue 134 if setty == "Grid text": 135 show_text = val 136 continue 137 if setty == "Grid color": 138 self.grid_color = val 139 continue 140 if setty == "Show side on": 141 self.show_side.setChecked( val ) 142 if setty == "Side direction": 143 self.directions.setCurrentText( val ) 144 145 ## if grid should be added, do it at the end when all values are updated 146 if add_grid: 147 self.add_grid() 148 self.viewer.layers["EpicGrid"].text.visible = show_text
Set current display to prefered settings
153 def add_display_overlay_message(self): 154 """ Shortcut list for display options """ 155 disptext = "--- Display options --- \n" 156 sdisp = self.epicure.shortcuts["Display"] 157 disptext += ut.print_shortcuts( sdisp ) 158 self.epicure.overtext["Display"] = disptext 159 sinfo = self.epicure.shortcuts["Info"] 160 self.epicure.overtext["info"] = "---- Info options --- \n" 161 self.epicure.overtext["info"] += ut.print_shortcuts( sinfo )
Shortcut list for display options
166 def key_bindings(self): 167 sdisp = self.epicure.shortcuts["Display"] 168 sinfo = self.epicure.shortcuts["Info"] 169 170 @self.seglayer.bind_key( sdisp["vis. segmentation"]["key"], overwrite=True ) 171 def see_segmentlayer(seglayer): 172 seglayer.visible = not seglayer.visible 173 174 @self.seglayer.bind_key( sdisp["vis. movie"]["key"], overwrite=True ) 175 def see_movielayer(seglayer): 176 ut.inv_visibility(self.viewer, "Movie") 177 178 @self.seglayer.bind_key( sdisp["vis. event"]["key"], overwrite=True ) 179 def see_eventslayer(seglayer): 180 evlayer = self.viewer.layers["Events"] 181 evlayer.visible = not evlayer.visible 182 183 @self.epicure.seglayer.bind_key( sinfo["measure length"]["key"], overwrite=True ) 184 def measure_length(layer): 185 """ 186 Draw a line and measure its length 187 """ 188 self.measure_line_length( layer ) 189 190 @self.seglayer.bind_key( sdisp["skeleton"]["key"], overwrite=True ) 191 def show_skeleton(seglayer): 192 """ On/Off show skeleton """ 193 if self.show_skeleton.isChecked(): 194 self.show_skeleton.setChecked(False) 195 else: 196 self.show_skeleton.setChecked(True) 197 198 @self.seglayer.bind_key( sdisp["show side"]["key"], overwrite=True ) 199 def show_byside(seglayer): 200 self.show_side.setChecked( not self.show_side.isChecked() ) 201 self.show_side_side() 202 203 @self.seglayer.bind_key( sdisp["increase"]["key"], overwrite=True ) 204 def contour_increase(seglayer): 205 if seglayer is not None: 206 seglayer.contour = seglayer.contour + 1 207 208 @self.seglayer.bind_key( sdisp["decrease"]["key"], overwrite=True ) 209 def contour_decrease(seglayer): 210 if seglayer is not None: 211 if seglayer.contour > 0: 212 seglayer.contour = seglayer.contour - 1 213 214 @self.seglayer.bind_key( sdisp["only movie"]["key"], overwrite=True ) 215 def see_onlymovielayer(seglayer): 216 """ if in "g" mode, show only movie, else put back to previous views """ 217 if self.gmode == 0: 218 self.lay_view = [] 219 for lay in self.viewer.layers: 220 self.lay_view.append( (lay, lay.visible) ) 221 lay.visible = False 222 ut.inv_visibility(self.viewer, "Movie") 223 self.gmode = 1 224 else: 225 for lay, vis in self.lay_view: 226 lay.visible = vis 227 self.gmode = 0 228 229 @self.seglayer.bind_key( sdisp["light view"]["key"], overwrite=True ) 230 def segmentation_lightmode(seglayer): 231 """ if in "d" mode, show only movie and light segmentation, else put back to previous views """ 232 if self.dmode == 0: 233 self.light_view = [] 234 for lay in self.viewer.layers: 235 self.light_view.append( (lay, lay.visible) ) 236 lay.visible = False 237 ut.inv_visibility(self.viewer, "Movie") 238 ut.inv_visibility(self.viewer, "Segmentation") 239 self.unlight_contour = self.seglayer.contour 240 self.unlight_opacity = self.seglayer.opacity 241 self.seglayer.contour = 1 242 self.seglayer.opacity = 0.2 243 self.dmode = 1 244 else: 245 for lay, vis in self.light_view: 246 lay.visible = vis 247 self.seglayer.contour = self.unlight_contour 248 self.seglayer.opacity = self.unlight_opacity 249 self.dmode = 0 250 251 @self.seglayer.bind_key( sdisp["grid"]["key"], overwrite=True ) 252 def show_grid(seglayer): 253 """ show/hide the grid to have a repere in space """ 254 self.show_grid()
257 def measure_line_length(self, layer=None): 258 """ 259 Draw a line and measure its length 260 """ 261 self.old_mouse_drag, self.old_key_map = ut.clear_bindings( self.epicure.seglayer ) 262 ut.show_info("Draw line to measure.") 263 if self.shapelayer_name not in self.viewer.layers: 264 self.create_shapelayer() 265 shape_lay = self.viewer.layers[self.shapelayer_name] 266 shape_lay.mode = "add_line" 267 shape_lay.visible = True 268 ut.set_active_layer( self.viewer, self.shapelayer_name) 269 270 @shape_lay.mouse_drag_callbacks.append 271 def click(layer, event): 272 if (event.type == "mouse_press") and (len(event.modifiers)==0) and (event.button==1): 273 ## dragg click to draw line 274 start_pos = event.position 275 yield 276 while event.type == 'mouse_move': 277 #print( event.position) 278 yield 279 end_pos = event.position 280 self.draw_line(shape_lay, start_pos, end_pos) 281 self.end_measure_mode() 282 else: 283 self.end_measure_mode()
Draw a line and measure its length
285 def end_measure_mode(self): 286 """ Finish measuring mode """ 287 if self.old_mouse_drag is not None: 288 if self.shapelayer_name in self.viewer.layers: 289 shape_lay = self.viewer.layers[self.shapelayer_name] 290 shape_lay.visible = False 291 ut.reactive_bindings( self.epicure.seglayer, self.old_mouse_drag, self.old_key_map ) 292 ut.show_info("End measure") 293 ut.set_active_layer( self.viewer, "Segmentation" )
Finish measuring mode
295 def draw_line( self, shape_lay, start_position, end_position ): 296 """ Draw a line in the shape layer """ 297 #shape_lay.data = np.array( [start_position, end_position] ) 298 #shape_lay.features = { "length": np.linalg.norm(np.array(end_position[1:3]) - np.array(start_position[1:3])) } 299 length = np.linalg.norm(np.array(end_position[1:3]) - np.array(start_position[1:3])) 300 ut.setOverlayText( self.viewer, "Length: "+str(round(length,1))+" µm" ) 301 #shape_lay.text.string = "length" 302 #shape_lay.text.visible = True 303 shape_lay.data = shape_lay.data[:-1] ## remove last line drawn 304 shape_lay.refresh()
Draw a line in the shape layer
307 def show_summary_window(self): 308 """ Show a text window with some infos """ 309 summwin = TextEdit() 310 summwin.name = "Epicure summary" 311 summwin.value = self.epicure.get_summary() 312 summwin.show()
Show a text window with some infos
315 def show_skeleton_segmentation(self): 316 """ Show/hide/update skeleton """ 317 if "Skeleton" in self.viewer.layers: 318 ut.remove_layer(self.viewer, "Skeleton") 319 if self.show_skeleton.isChecked(): 320 self.epicure.add_skeleton() 321 ut.set_active_layer( self.viewer, "Segmentation" )
Show/hide/update skeleton
323 def show_side_side( self ): 324 """ Show the layers side by side """ 325 layout_grid = self.viewer.grid 326 if self.show_side.isChecked(): 327 stride = len( self.viewer.layers ) - 1 328 layout_grid.stride = stride 329 layout_grid.shape = (2,1) 330 if self.directions.currentText() == "Horizontal": 331 layout_grid.shape = (1,2) 332 layout_grid.enabled = True 333 else: 334 layout_grid.enabled = False
Show the layers side by side
337 def show_shifted_segmentation(self): 338 """ Show/Hide temporally shifted segmentation on top of current one """ 339 if ("PrevSegmentation" in self.viewer.layers): 340 if (not self.show_shifted.isChecked()): 341 ut.remove_layer(self.viewer, "PrevSegmentation") 342 else: 343 lay = self.viewer.layers["PrevSegmentation"] 344 lay.refresh() 345 346 if ("PrevSegmentation" not in self.viewer.layers) and (self.show_shifted.isChecked()): 347 if self.epicure.nframes > 1: 348 layer = self.viewer.add_labels( self.seglayer.data, name="PrevSegmentation", blending="additive", opacity=0.4 ) 349 layer.contour = 2 350 layer.translate = [1, 0, 0] 351 self.seglayer.contour = 2 352 self.seglayer.opacity = 0.6 353 else: 354 ut.show_warning("Still image, cannot show previous frames") 355 356 ut.set_active_layer( self.viewer, "Segmentation" )
Show/Hide temporally shifted segmentation on top of current one
358 def show_shifted_previous_movie(self): 359 """ Show/Hide temporally shifted movie previous frame on top of current one """ 360 self.show_shifted_movie("PrevMovie", "red", 1)
Show/Hide temporally shifted movie previous frame on top of current one
362 def show_shifted_next_movie(self): 363 """ Show/Hide temporally shifted movie next frame on top of current one """ 364 self.show_shifted_movie("NextMovie", "green", -1)
Show/Hide temporally shifted movie next frame on top of current one
366 def show_shifted_movie(self, layname, color, translation): 367 """ Show/Hide temporally shifted movie on top of current one """ 368 if (layname in self.viewer.layers): 369 if (not self.show_previous_movie.isChecked()): 370 ut.remove_layer(self.viewer, layname) 371 else: 372 lay = self.viewer.layers[layname] 373 lay.refresh() 374 375 if (layname not in self.viewer.layers) and (self.show_previous_movie.isChecked()): 376 if self.epicure.nframes > 1: 377 movlay = self.viewer.layers["Movie"] 378 arr = movlay.data 379 if translation == -1: 380 arr = movlay.data[1:,] 381 layer = self.viewer.add_image( arr, name=layname, blending="additive", opacity=0.6, colormap=color ) 382 if translation == 1: 383 layer.translate = [translation, 0, 0] 384 layer.contrast_limits=self.epicure.quantiles() 385 layer.gamma=0.94 386 else: 387 ut.show_warning("Still image, cannot show previous frames") 388 389 ut.set_active_layer( self.viewer, "Segmentation" )
Show/Hide temporally shifted movie on top of current one
392 def grid_parameters(self): 393 """ Interface to get grid parameters """ 394 grid_layout = QVBoxLayout() 395 ## nrows 396 rows_line, self.nrows = wid.value_line( "Nb rows", "4", "Number of rows of the grid" ) 397 grid_layout.addLayout(rows_line) 398 ## ncols 399 cols_line, self.ncols = wid.value_line( "Nb columns:", "4", "Number of columns in the grid" ) 400 grid_layout.addLayout(cols_line) 401 ## grid edges width 402 width_line, self.gwidth = wid.value_line( "Grid width:", "3", "Width of the grid displayed lines/columns" ) 403 grid_layout.addLayout(width_line) 404 ## go for grid 405 btn_add_grid = wid.add_button( "Add grid", self.add_grid, "Add a grid overlay to the main view" ) 406 grid_layout.addWidget(btn_add_grid) 407 self.group_grid.setLayout(grid_layout)
Interface to get grid parameters
409 def add_grid(self): 410 """ Create/Load a new grid and add it """ 411 ut.remove_layer(self.viewer, "EpicGrid") 412 imshape = self.epicure.imgshape2D 413 if imshape is None: 414 ut.show_error("Load the image first") 415 return 416 nrows = int(self.nrows.text()) 417 ncols = int(self.ncols.text()) 418 wid = ceil(imshape[0]/nrows) 419 hei = ceil(imshape[1]/ncols) 420 rects = [] 421 rects_names = [] 422 gwidth = int(self.gwidth.text()) 423 for x in range(nrows): 424 for y in range(ncols): 425 rect = np.array([[x*wid, y*hei], [(x+1)*wid, (y+1)*hei]]) 426 rects.append(rect) 427 rects_names.append(chr(65+x)+"_"+str(y)) 428 self.viewer.add_shapes(rects, name="EpicGrid", text=rects_names, face_color=[1,0,0,0], edge_color=self.grid_color, edge_width=gwidth, opacity=0.7, scale=self.viewer.layers["Segmentation"].scale[1:]) 429 self.viewer.layers["EpicGrid"].text.visible = False 430 ut.set_active_layer( self.viewer, "Segmentation" )
Create/Load a new grid and add it
432 def show_grid(self): 433 """ Interface to create/load a grid for repere """ 434 if "EpicGrid" not in self.viewer.layers: 435 self.add_grid() 436 else: 437 gridlay = self.viewer.layers["EpicGrid"] 438 gridlay.visible = not gridlay.visible 439 gridlay.edge_color = self.grid_color
Interface to create/load a grid for repere