def _initColors(self): self.mergerColors = [ QColor(c) for c in LabelingGui._createDefault16ColorColorTable()[1:] ] self.mergerColors[0] = QColor(0,0,0,0) # 0 and 1 must be transparent self.mergerColors[1] = QColor(0,0,0,0)
def hideEvent(self, event): #Ensure interactive is toggled of when leaving this GUI self.toggleInteractive(False) self.labelingDrawerUi.liveUpdateButton.setChecked(False) LabelingGui.hideEvent(self, event)
def __init__(self, parentApplet, topLevelOperatorView, drawerUiPath=None): self.topLevelOperatorView = topLevelOperatorView #members self._doneSegmentationLayer = None self._showSegmentationIn3D = False #self._showUncertaintyLayer = False #end: members labelingSlots = LabelingGui.LabelingSlots() labelingSlots.labelInput = topLevelOperatorView.WriteSeeds labelingSlots.labelOutput = topLevelOperatorView.opLabelArray.Output labelingSlots.labelEraserValue = topLevelOperatorView.opLabelArray.EraserLabelValue labelingSlots.labelNames = topLevelOperatorView.LabelNames labelingSlots.labelDelete = topLevelOperatorView.opLabelArray.DeleteLabel labelingSlots.maxLabelValue = topLevelOperatorView.opLabelArray.MaxLabelValue labelingSlots.labelsAllowed = topLevelOperatorView.LabelsAllowed # We provide our own UI file (which adds an extra control for interactive mode) directory = os.path.split(__file__)[0] if drawerUiPath is None: drawerUiPath = os.path.join(directory, 'carvingDrawer.ui') self.dialogdirCOM = os.path.join(directory, 'carvingObjectManagement.ui') self.dialogdirSAD = os.path.join(directory, 'saveAsDialog.ui') rawInputSlot = topLevelOperatorView.RawData super(CarvingGui, self).__init__(parentApplet, labelingSlots, topLevelOperatorView, drawerUiPath, rawInputSlot) self.labelingDrawerUi.currentObjectLabel.setText("<not saved yet>") # Init special base class members self.minLabelNumber = 2 self.maxLabelNumber = 2 mgr = ShortcutManager() ActionInfo = ShortcutManager.ActionInfo #set up keyboard shortcuts mgr.register( "3", ActionInfo("Carving", "Run interactive segmentation", "Run interactive segmentation", self.labelingDrawerUi.segment.click, self.labelingDrawerUi.segment, self.labelingDrawerUi.segment)) try: self.render = True self._shownObjects3D = {} self._renderMgr = RenderingManager(self.editor.view3d) except: self.render = False # Segmentation is toggled on by default in _after_init, below. # (We can't enable it until the layers are all present.) self._showSegmentationIn3D = False self._segmentation_3d_label = None self.labelingDrawerUi.segment.clicked.connect(self.onSegmentButton) self.labelingDrawerUi.segment.setEnabled(True) self.topLevelOperatorView.Segmentation.notifyDirty( bind(self._update_rendering)) self.topLevelOperatorView.HasSegmentation.notifyValueChanged( bind(self._updateGui)) ## uncertainty #self.labelingDrawerUi.pushButtonUncertaintyFG.setEnabled(False) #self.labelingDrawerUi.pushButtonUncertaintyBG.setEnabled(False) #def onUncertaintyFGButton(): # logger.debug( "uncertFG button clicked" ) # pos = self.topLevelOperatorView.getMaxUncertaintyPos(label=2) # self.editor.posModel.slicingPos = (pos[0], pos[1], pos[2]) #self.labelingDrawerUi.pushButtonUncertaintyFG.clicked.connect(onUncertaintyFGButton) #def onUncertaintyBGButton(): # logger.debug( "uncertBG button clicked" ) # pos = self.topLevelOperatorView.getMaxUncertaintyPos(label=1) # self.editor.posModel.slicingPos = (pos[0], pos[1], pos[2]) #self.labelingDrawerUi.pushButtonUncertaintyBG.clicked.connect(onUncertaintyBGButton) #def onUncertaintyCombo(value): # if value == 0: # value = "none" # self.labelingDrawerUi.pushButtonUncertaintyFG.setEnabled(False) # self.labelingDrawerUi.pushButtonUncertaintyBG.setEnabled(False) # self._showUncertaintyLayer = False # else: # if value == 1: # value = "localMargin" # elif value == 2: # value = "exchangeCount" # elif value == 3: # value = "gabow" # else: # raise RuntimeError("unhandled case '%r'" % value) # self.labelingDrawerUi.pushButtonUncertaintyFG.setEnabled(True) # self.labelingDrawerUi.pushButtonUncertaintyBG.setEnabled(True) # self._showUncertaintyLayer = True # logger.debug( "uncertainty changed to %r" % value ) # self.topLevelOperatorView.UncertaintyType.setValue(value) # self.updateAllLayers() #make sure that an added/deleted uncertainty layer is recognized #self.labelingDrawerUi.uncertaintyCombo.currentIndexChanged.connect(onUncertaintyCombo) ## background priority def onBackgroundPrioritySpin(value): logger.debug("background priority changed to %f" % value) self.topLevelOperatorView.BackgroundPriority.setValue(value) self.labelingDrawerUi.backgroundPrioritySpin.valueChanged.connect( onBackgroundPrioritySpin) def onBackgroundPriorityDirty(slot, roi): oldValue = self.labelingDrawerUi.backgroundPrioritySpin.value() newValue = self.topLevelOperatorView.BackgroundPriority.value if newValue != oldValue: self.labelingDrawerUi.backgroundPrioritySpin.setValue(newValue) self.topLevelOperatorView.BackgroundPriority.notifyDirty( onBackgroundPriorityDirty) ## bias def onNoBiasBelowDirty(slot, roi): oldValue = self.labelingDrawerUi.noBiasBelowSpin.value() newValue = self.topLevelOperatorView.NoBiasBelow.value if newValue != oldValue: self.labelingDrawerUi.noBiasBelowSpin.setValue(newValue) self.topLevelOperatorView.NoBiasBelow.notifyDirty(onNoBiasBelowDirty) def onNoBiasBelowSpin(value): logger.debug("background priority changed to %f" % value) self.topLevelOperatorView.NoBiasBelow.setValue(value) self.labelingDrawerUi.noBiasBelowSpin.valueChanged.connect( onNoBiasBelowSpin) ## save self.labelingDrawerUi.save.clicked.connect(self.onSaveButton) ## clear self.labelingDrawerUi.clear.clicked.connect(self._onClearAction) ## object names self.labelingDrawerUi.namesButton.clicked.connect( self.onShowObjectNames) if hasattr(self.labelingDrawerUi, 'exportAllMeshesButton'): self.labelingDrawerUi.exportAllMeshesButton.clicked.connect( self._exportAllObjectMeshes) self.labelingDrawerUi.labelListView.allowDelete = False self._labelControlUi.labelListModel.allowRemove(False) def layerIndexForName(name): return self.layerstack.findMatchingIndex(lambda x: x.name == name) def addLayerToggleShortcut(layername, shortcut): def toggle(): row = layerIndexForName(layername) self.layerstack.selectRow(row) layer = self.layerstack[row] layer.visible = not layer.visible self.viewerControlWidget().layerWidget.setFocus() mgr.register( shortcut, ActionInfo("Carving", "Toggle layer %s" % layername, "Toggle layer %s" % layername, toggle, self.viewerControlWidget(), None)) #TODO addLayerToggleShortcut("Completed segments (unicolor)", "d") addLayerToggleShortcut("Segmentation", "s") addLayerToggleShortcut("Input Data", "r") ''' def updateLayerTimings(): s = "Layer timings:\n" for l in self.layerstack: s += "%s: %f sec.\n" % (l.name, l.averageTimePerTile) self.labelingDrawerUi.layerTimings.setText(s) t = QTimer(self) t.setInterval(1*1000) # 10 seconds t.start() t.timeout.connect(updateLayerTimings) ''' def makeColortable(): self._doneSegmentationColortable = [QColor(0, 0, 0, 0).rgba()] for i in range(254): r, g, b = numpy.random.randint(0, 255), numpy.random.randint( 0, 255), numpy.random.randint(0, 255) # ensure colors have sufficient distance to pure red and pure green while (255 - r) + g + b < 128 or r + (255 - g) + b < 128: r, g, b = numpy.random.randint( 0, 255), numpy.random.randint( 0, 255), numpy.random.randint(0, 255) self._doneSegmentationColortable.append(QColor(r, g, b).rgba()) self._doneSegmentationColortable.append(QColor(0, 255, 0).rgba()) makeColortable() def onRandomizeColors(): if self._doneSegmentationLayer is not None: logger.debug("randomizing colors ...") makeColortable() self._doneSegmentationLayer.colorTable = self._doneSegmentationColortable if self.render and self._renderMgr.ready: self._update_rendering() #self.labelingDrawerUi.randomizeColors.clicked.connect(onRandomizeColors) self._updateGui()
def __init__(self, parentApplet, op): self.__cleanup_fns = [] # Tell our base class which slots to monitor labelSlots = LabelingGui.LabelingSlots() labelSlots.labelInput = op.LabelInputs labelSlots.labelOutput = op.LabelImages labelSlots.labelEraserValue = op.Eraser labelSlots.labelDelete = op.DeleteLabel labelSlots.maxLabelValue = op.NumLabels labelSlots.labelNames = op.LabelNames # We provide our own UI file (which adds an extra control for # interactive mode) This UI file is copied from # pixelClassification pipeline # labelingDrawerUiPath = os.path.split( __file__)[0] + '/labelingDrawer.ui' # Base class init super(ObjectClassificationGui, self).__init__(parentApplet, labelSlots, op, labelingDrawerUiPath, crosshair=False) self.op = op self.applet = parentApplet self.threadRouter = ThreadRouter(self) op.Warnings.notifyDirty(self.handleWarnings) self.__cleanup_fns.append( partial(op.Warnings.unregisterDirty, self.handleWarnings)) self._retained_weakrefs = [] # unused self.labelingDrawerUi.savePredictionsButton.setEnabled(False) self.labelingDrawerUi.savePredictionsButton.setVisible(False) self.labelingDrawerUi.brushSizeComboBox.setEnabled(False) self.labelingDrawerUi.brushSizeComboBox.setVisible(False) self.labelingDrawerUi.brushSizeCaption.setVisible(False) self._colorTable16_forpmaps = self._createDefault16ColorColorTable() self._colorTable16_forpmaps[15] = QColor( Qt.black).rgba() #for objects with NaNs in features # button handlers self._interactiveMode = False self._showPredictions = False self._labelMode = True self.labelingDrawerUi.subsetFeaturesButton.clicked.connect( self.handleSubsetFeaturesClicked) self.labelingDrawerUi.labelAssistButton.clicked.connect( self.handleLabelAssistClicked) self.labelingDrawerUi.checkInteractive.toggled.connect( self.handleInteractiveModeClicked) self.labelingDrawerUi.checkShowPredictions.toggled.connect( self.handleShowPredictionsClicked) #select all the features in the beginning cfn = None already_selected = None if self.op.ComputedFeatureNames.ready(): cfn = self.op.ComputedFeatureNames[:].wait() if self.op.SelectedFeatures.ready(): already_selected = self.op.SelectedFeatures[:].wait() if already_selected is None or len(already_selected) == 0: if cfn is not None: already_selected = cfn self.op.SelectedFeatures.setValue(already_selected) nfeatures = 0 if already_selected is not None: for plugin_features in already_selected.values(): nfeatures += len(plugin_features) self.labelingDrawerUi.featuresSubset.setText( "{} features selected,\nsome may have multiple channels".format( nfeatures)) # enable/disable buttons logic self.op.ObjectFeatures.notifyDirty(bind(self.checkEnableButtons)) self.__cleanup_fns.append( partial(op.ObjectFeatures.unregisterDirty, bind(self.checkEnableButtons))) self.op.NumLabels.notifyReady(bind(self.checkEnableButtons)) self.__cleanup_fns.append( partial(op.NumLabels.unregisterReady, bind(self.checkEnableButtons))) self.op.NumLabels.notifyDirty(bind(self.checkEnableButtons)) self.__cleanup_fns.append( partial(op.NumLabels.unregisterDirty, bind(self.checkEnableButtons))) self.op.SelectedFeatures.notifyDirty(bind(self.checkEnableButtons)) self.__cleanup_fns.append( partial(op.SelectedFeatures.unregisterDirty, bind(self.checkEnableButtons))) if not self.op.AllowAddLabel([]).wait()[0]: self.labelingDrawerUi.AddLabelButton.hide() self.labelingDrawerUi.AddLabelButton.clicked.disconnect() self.badObjectBox = None self.checkEnableButtons() self._labelAssistDialog = None
def __init__(self, parentApplet, topLevelOperatorView, labelingDrawerUiPath=None): self.parentApplet = parentApplet self.isInitialized = ( False # need this flag in pixelClassificationApplet where initialization is terminated with label selection ) # Tell our base class which slots to monitor labelSlots = LabelingGui.LabelingSlots() labelSlots.labelInput = topLevelOperatorView.LabelInputs labelSlots.labelOutput = topLevelOperatorView.LabelImages labelSlots.labelEraserValue = topLevelOperatorView.opLabelPipeline.opLabelArray.eraser labelSlots.labelDelete = topLevelOperatorView.opLabelPipeline.DeleteLabel labelSlots.labelNames = topLevelOperatorView.LabelNames self.__cleanup_fns = [] # We provide our own UI file (which adds an extra control for interactive mode) if labelingDrawerUiPath is None: labelingDrawerUiPath = os.path.split( __file__)[0] + "/labelingDrawer.ui" # Base class init super(PixelClassificationGui, self).__init__(parentApplet, labelSlots, topLevelOperatorView, labelingDrawerUiPath, topLevelOperatorView.InputImages) self.topLevelOperatorView = topLevelOperatorView self._currentlySavingPredictions = False self.labelingDrawerUi.labelListView.support_merges = True self.labelingDrawerUi.liveUpdateButton.toggled.connect( self.setLiveUpdateEnabled) self.initFeatSelDlg() self.labelingDrawerUi.suggestFeaturesButton.clicked.connect( self.show_feature_selection_dialog) self.featSelDlg.accepted.connect(self.update_features_from_dialog) self.labelingDrawerUi.suggestFeaturesButton.setEnabled(False) # Always force at least two labels because it makes no sense to have less here self.forceAtLeastTwoLabels(True) self._initShortcuts() self._bookmarks_window = BookmarksWindow(self, self.topLevelOperatorView) # FIXME: We MUST NOT enable the render manager by default, # since it will drastically slow down the app for large volumes. # For now, we leave it off by default. # To re-enable rendering, we need to allow the user to render a segmentation # and then initialize the render manager on-the-fly. # (We might want to warn the user if her volume is not small.) self.render = False self._renderMgr = None self._renderedLayers = {} # (layer name, label number) # Always off for now (see note above) if self.render: try: self._renderMgr = RenderingManager(self.editor.view3d) except: self.render = False # listen to freezePrediction changes unsub_callback = self.topLevelOperatorView.FreezePredictions.notifyDirty( lambda *args: self.setLiveUpdateEnabled()) self.__cleanup_fns.append(unsub_callback) self.setLiveUpdateEnabled()