Example #1
0
    def setupLayers(self):
        mainOperator = self.topLevelOperatorView
        layers = []

        if mainOperator.ObjectCenterImage.ready():
            self.centerimagesrc = LazyflowSource(mainOperator.ObjectCenterImage)
            redct = [0, QColor(255, 0, 0).rgba()]
            layer = ColortableLayer(self.centerimagesrc, redct)
            layer.name = "Object centers"
            layer.setToolTip("Object center positions, marked with a little red cross")
            layer.visible = False
            layers.append(layer)

        ct = colortables.create_default_16bit()
        if mainOperator.LabelImage.ready():
            self.objectssrc = LazyflowSource(mainOperator.LabelImage)
            self.objectssrc.setObjectName("LabelImage LazyflowSrc")
            ct[0] = QColor(0, 0, 0, 0).rgba() # make 0 transparent
            layer = ColortableLayer(self.objectssrc, ct)
            layer.name = "Objects (connected components)"
            layer.setToolTip("Segmented objects, shown in different colors")
            layer.visible = False
            layer.opacity = 0.5
            layers.append(layer)

        # white foreground on transparent background, even for labeled images
        binct = [QColor(255, 255, 255, 255).rgba()]*65536
        binct[0] = 0
        if mainOperator.BinaryImage.ready():
            self.binaryimagesrc = LazyflowSource(mainOperator.BinaryImage)
            self.binaryimagesrc.setObjectName("Binary LazyflowSrc")
            layer = ColortableLayer(self.binaryimagesrc, binct)
            layer.name = "Binary image"
            layer.setToolTip("Segmented objects, binary mask")
            layers.append(layer)

        ## raw data layer
        self.rawsrc = None
        self.rawsrc = LazyflowSource(mainOperator.RawImage)
        self.rawsrc.setObjectName("Raw Lazyflow Src")
        layerraw = GrayscaleLayer(self.rawsrc)
        layerraw.name = "Raw data"
        layers.insert(len(layers), layerraw)

        mainOperator.RawImage.notifyReady(self._onReady)
        self.__cleanup_fns.append( partial( mainOperator.RawImage.unregisterReady, self._onReady ) )

        mainOperator.RawImage.notifyMetaChanged(self._onMetaChanged)
        self.__cleanup_fns.append( partial( mainOperator.RawImage.unregisterMetaChanged, self._onMetaChanged ) )

        if mainOperator.BinaryImage.meta.shape:
            self.editor.dataShape = mainOperator.BinaryImage.meta.shape

        mainOperator.BinaryImage.notifyMetaChanged(self._onMetaChanged)
        self.__cleanup_fns.append( partial( mainOperator.BinaryImage.unregisterMetaChanged, self._onMetaChanged ) )

        return layers
 def addCCOperator(self):
     self.opCC = OpConnectedComponents(self.g)
     self.opCC.inputs["Input"].connect(self.opThreshold.outputs["Output"])
     #we shouldn't have to define these. But just in case...
     self.opCC.inputs["Neighborhood"].setValue(6)
     self.opCC.inputs["Background"].setValue(0)
     
     ccsrc = LazyflowSource(self.opCC.outputs["Output"][0])
     ccsrc.setObjectName("Connected Components")
     ctb = colortables.create_default_16bit()
     ctb.insert(0, QColor(0, 0, 0, 0).rgba()) # make background transparent
     ccLayer = ColortableLayer(ccsrc, ctb)
     ccLayer.name = "Connected Components"
     self.layerstack.insert(1, ccLayer)
Example #3
0
    def setupLayers(self):
        mainOperator = self.topLevelOperatorView
        layers = []

        if mainOperator.ObjectCenterImage.ready():
            self.centerimagesrc = LazyflowSource(mainOperator.ObjectCenterImage)
            #layer = RGBALayer(red=ConstantSource(255), alpha=self.centerimagesrc)
            redct = [0, QColor(255, 0, 0).rgba()]
            layer = ColortableLayer(self.centerimagesrc, redct)
            layer.name = "Object Centers"
            layer.visible = False
            layers.append(layer)

        ct = colortables.create_default_16bit()
        if mainOperator.LabelImage.ready():
            self.objectssrc = LazyflowSource(mainOperator.LabelImage)
            self.objectssrc.setObjectName("LabelImage LazyflowSrc")
            ct[0] = QColor(0, 0, 0, 0).rgba() # make 0 transparent
            layer = ColortableLayer(self.objectssrc, ct)
            layer.name = "Label Image"
            layer.visible = False
            layer.opacity = 0.5
            layers.append(layer)

        # white foreground on transparent background
        binct = [QColor(0, 0, 0, 0).rgba(), QColor(255, 255, 255, 255).rgba()]
        if mainOperator.BinaryImage.ready():
            self.binaryimagesrc = LazyflowSource(mainOperator.BinaryImage)
            self.binaryimagesrc.setObjectName("Binary LazyflowSrc")
            layer = ColortableLayer(self.binaryimagesrc, binct)
            layer.name = "Binary Image"
            layers.append(layer)

        ## raw data layer
        self.rawsrc = None
        self.rawsrc = LazyflowSource(mainOperator.RawImage)
        self.rawsrc.setObjectName("Raw Lazyflow Src")
        layerraw = GrayscaleLayer(self.rawsrc)
        layerraw.name = "Raw"
        layers.insert(len(layers), layerraw)

        mainOperator.RawImage.notifyReady(self._onReady)
        mainOperator.RawImage.notifyMetaChanged(self._onMetaChanged)

        if mainOperator.BinaryImage.meta.shape:
            self.editor.dataShape = mainOperator.BinaryImage.meta.shape
        mainOperator.BinaryImage.notifyMetaChanged(self._onMetaChanged)

        return layers
Example #4
0
 def _onReady(self, slot):
     if slot is self.topLevelOperatorView.RawImage:
         if slot.meta.shape and not self.rawsrc:
             self.rawsrc = LazyflowSource(self.topLevelOperatorView.RawImage)
             layerraw = GrayscaleLayer(self.rawsrc)
             layerraw.name = "Raw data"
             self.layerstack.append(layerraw)
    def _onMetaChanged(self, slot):
        if slot is self.mainOperator.BinaryImage:
            if slot.meta.shape:
                self.editor.dataShape = slot.meta.shape

        if slot is self.mainOperator.RawImage:
            if slot.meta.shape and not self.rawsrc:
                self.rawsrc = LazyflowSource(self.mainOperator.RawImage)
                layerraw = GrayscaleLayer(self.rawsrc)
                layerraw.name = "Raw"
                self.layerstack.append(layerraw)
 def addThresholdOperator(self):
     if self.opThreshold is None:
         self.opThreshold = OpThreshold(self.g)
         self.opThreshold.inputs["Input"].connect(self.pCache.outputs["Output"])
     #channel, value = ThresholdDlg(self.labelListModel._labels)
     channel = 0
     value = 0.5
     ref_label = self.labelListModel._labels[channel]
     self.opThreshold.inputs["Channel"].setValue(channel)
     self.opThreshold.inputs["Threshold"].setValue(value)
     threshsrc = LazyflowSource(self.opThreshold.outputs["Output"][0])
     
     threshsrc.setObjectName("Threshold for %s" % ref_label.name)
     transparent = QColor(0,0,0,0)
     white = QColor(255,255,255)
     colorTable = [transparent.rgba(), white.rgba()]
     threshLayer = ColortableLayer(threshsrc, colorTable = colorTable )
     threshLayer.name = "Threshold for %s" % ref_label.name
     self.layerstack.insert(1, threshLayer)
     self.CCButton.setEnabled(True)
Example #7
0
    def _onMetaChanged(self, slot):
        #FiXME: why do we need that?
        if slot is self.topLevelOperatorView.BinaryImage:
            if slot.meta.shape:
                self.editor.dataShape = slot.meta.shape

        if slot is self.topLevelOperatorView.RawImage:
            if slot.meta.shape and not self.rawsrc:
                self.rawsrc = LazyflowSource(self.topLevelOperatorView.RawImage)
                layerraw = GrayscaleLayer(self.rawsrc)
                layerraw.name = "Raw data"
                self.layerstack.append(layerraw)
Example #8
0
class ObjectExtractionGui(QWidget):

    ###########################################
    ### AppletGuiInterface Concrete Methods ###
    ###########################################

    def centralWidget(self):
        """ Return the widget that will be displayed in the main viewer area. """
        return self.volumeEditorWidget

    def appletDrawer(self):
        return self._drawer

    def menus(self):
        return []

    def viewerControlWidget(self):
        return self._viewerControlWidget

    def stopAndCleanUp(self):
        pass

    ###########################################
    ###########################################

    def __init__(self, topLevelOperatorView):
        super(ObjectExtractionGui, self).__init__()
        self.mainOperator = topLevelOperatorView
        self.layerstack = LayerStackModel()

        self._viewerControlWidget = None
        self._initViewerControlUi()

        self.editor = None
        self._initEditor()

        self._initAppletDrawerUi()
        assert(self.appletDrawer() is not None)
        self._initViewer()


    def _onMetaChanged(self, slot):
        if slot is self.mainOperator.BinaryImage:
            if slot.meta.shape:
                self.editor.dataShape = slot.meta.shape

        if slot is self.mainOperator.RawImage:
            if slot.meta.shape and not self.rawsrc:
                self.rawsrc = LazyflowSource(self.mainOperator.RawImage)
                layerraw = GrayscaleLayer(self.rawsrc)
                layerraw.name = "Raw"
                self.layerstack.append(layerraw)

    def _onReady(self, slot):
        if slot is self.mainOperator.RawImage:
            if slot.meta.shape and not self.rawsrc:
                self.rawsrc = LazyflowSource(self.mainOperator.RawImage)
                layerraw = GrayscaleLayer(self.rawsrc)
                layerraw.name = "Raw"
                self.layerstack.append(layerraw)

    def _initViewer(self):
        mainOperator = self.mainOperator

        # white foreground on transparent background
        ct = [QColor(0, 0, 0, 0).rgba(),
              QColor(255, 255, 255, 255).rgba()]
        self.binaryimagesrc = LazyflowSource(mainOperator.BinaryImage)
        self.binaryimagesrc.setObjectName("Binary LazyflowSrc")
        layer = ColortableLayer(self.binaryimagesrc, ct)
        layer.name = "Binary Image"
        self.layerstack.append(layer)

        ct = colortables.create_default_16bit()
        self.objectssrc = LazyflowSource(mainOperator.LabelImage)
        self.objectssrc.setObjectName("LabelImage LazyflowSrc")
        ct[0] = QColor(0, 0, 0, 0).rgba() # make 0 transparent
        layer = ColortableLayer(self.objectssrc, ct)
        layer.name = "Label Image"
        layer.visible = False
        layer.opacity = 0.5
        self.layerstack.append(layer)

        self.centerimagesrc = LazyflowSource(mainOperator.ObjectCenterImage)
        layer = RGBALayer(red=ConstantSource(255), alpha=self.centerimagesrc)
        layer.name = "Object Centers"
        layer.visible = False
        self.layerstack.append(layer)

        ## raw data layer
        self.rawsrc = None
        self.rawsrc = LazyflowSource(self.mainOperator.RawImage)
        self.rawsrc.setObjectName("Raw Lazyflow Src")
        layerraw = GrayscaleLayer(self.rawsrc)
        layerraw.name = "Raw"
        self.layerstack.insert(len(self.layerstack), layerraw)

        mainOperator.RawImage.notifyReady(self._onReady)
        mainOperator.RawImage.notifyMetaChanged(self._onMetaChanged)

        if mainOperator.BinaryImage.meta.shape:
            self.editor.dataShape = mainOperator.BinaryImage.meta.shape
        mainOperator.BinaryImage.notifyMetaChanged(self._onMetaChanged)

    def _initEditor(self):
        """Initialize the Volume Editor GUI."""

        self.editor = VolumeEditor(self.layerstack, crosshair=False)

        self.volumeEditorWidget = VolumeEditorWidget()
        self.volumeEditorWidget.init(self.editor)

        # The editor's layerstack is in charge of which layer movement buttons are enabled
        model = self.editor.layerStack
        model.canMoveSelectedUp.connect(self._viewerControlWidget.UpButton.setEnabled)
        model.canMoveSelectedDown.connect(self._viewerControlWidget.DownButton.setEnabled)
        model.canDeleteSelected.connect(self._viewerControlWidget.DeleteButton.setEnabled)

        # Connect our layer movement buttons to the appropriate layerstack actions
        self._viewerControlWidget.layerWidget.init(model)
        self._viewerControlWidget.UpButton.clicked.connect(model.moveSelectedUp)
        self._viewerControlWidget.DownButton.clicked.connect(model.moveSelectedDown)
        self._viewerControlWidget.DeleteButton.clicked.connect(model.deleteSelected)

        self.editor._lastImageViewFocus = 0

    def _initAppletDrawerUi(self):
        # Load the ui file (find it in our own directory)
        localDir = os.path.split(__file__)[0]
        self._drawer = uic.loadUi(localDir+"/drawer.ui")

        self._drawer.calculateFeaturesButton.pressed.connect(self._calculateFeaturesButtonPressed)

    def _initViewerControlUi(self):
        p = os.path.split(__file__)[0]+'/'
        if p == "/": p = "."+p
        self._viewerControlWidget = uic.loadUi(p+"viewerControls.ui")

    def _calculateFeaturesButtonPressed(self):
        maxt = self.mainOperator.LabelImage.meta.shape[0]
        progress = QProgressDialog("Calculating featuers...", "Stop", 0, maxt)
        progress.setWindowModality(Qt.ApplicationModal)
        progress.setMinimumDuration(0)
        progress.setCancelButtonText(QString())

        reqs = []
        self.mainOperator._opRegFeats.fixed = False
        for t in range(maxt):
            reqs.append(self.mainOperator.RegionFeatures([t]))
            reqs[-1].submit()

        for i, req in enumerate(reqs):
            progress.setValue(i)
            if progress.wasCanceled():
                req.cancel()
            else:
                req.wait()

        self.mainOperator._opRegFeats.fixed = True
        progress.setValue(maxt)

        self.mainOperator.ObjectCenterImage.setDirty(SubRegion(self.mainOperator.ObjectCenterImage))

        print 'Object Extraction: done.'
Example #9
0
class ObjectExtractionGui(LayerViewerGui):

    def setupLayers(self):
        mainOperator = self.topLevelOperatorView
        layers = []

        if mainOperator.ObjectCenterImage.ready():
            self.centerimagesrc = LazyflowSource(mainOperator.ObjectCenterImage)
            #layer = RGBALayer(red=ConstantSource(255), alpha=self.centerimagesrc)
            redct = [0, QColor(255, 0, 0).rgba()]
            layer = ColortableLayer(self.centerimagesrc, redct)
            layer.name = "Object Centers"
            layer.visible = False
            layers.append(layer)

        ct = colortables.create_default_16bit()
        if mainOperator.LabelImage.ready():
            self.objectssrc = LazyflowSource(mainOperator.LabelImage)
            self.objectssrc.setObjectName("LabelImage LazyflowSrc")
            ct[0] = QColor(0, 0, 0, 0).rgba() # make 0 transparent
            layer = ColortableLayer(self.objectssrc, ct)
            layer.name = "Label Image"
            layer.visible = False
            layer.opacity = 0.5
            layers.append(layer)

        # white foreground on transparent background
        binct = [QColor(0, 0, 0, 0).rgba(), QColor(255, 255, 255, 255).rgba()]
        if mainOperator.BinaryImage.ready():
            self.binaryimagesrc = LazyflowSource(mainOperator.BinaryImage)
            self.binaryimagesrc.setObjectName("Binary LazyflowSrc")
            layer = ColortableLayer(self.binaryimagesrc, binct)
            layer.name = "Binary Image"
            layers.append(layer)

        ## raw data layer
        self.rawsrc = None
        self.rawsrc = LazyflowSource(mainOperator.RawImage)
        self.rawsrc.setObjectName("Raw Lazyflow Src")
        layerraw = GrayscaleLayer(self.rawsrc)
        layerraw.name = "Raw"
        layers.insert(len(layers), layerraw)

        mainOperator.RawImage.notifyReady(self._onReady)
        mainOperator.RawImage.notifyMetaChanged(self._onMetaChanged)

        if mainOperator.BinaryImage.meta.shape:
            self.editor.dataShape = mainOperator.BinaryImage.meta.shape
        mainOperator.BinaryImage.notifyMetaChanged(self._onMetaChanged)

        return layers

    def _onMetaChanged(self, slot):
        #FiXME: why do we need that?
        if slot is self.topLevelOperatorView.BinaryImage:
            if slot.meta.shape:
                self.editor.dataShape = slot.meta.shape

        if slot is self.topLevelOperatorView.RawImage:
            if slot.meta.shape and not self.rawsrc:
                self.rawsrc = LazyflowSource(self.topLevelOperatorView.RawImage)
                layerraw = GrayscaleLayer(self.rawsrc)
                layerraw.name = "Raw"
                self.layerstack.append(layerraw)

    def _onReady(self, slot):
        if slot is self.topLevelOperatorView.RawImage:
            if slot.meta.shape and not self.rawsrc:
                self.rawsrc = LazyflowSource(self.topLevelOperatorView.RawImage)
                layerraw = GrayscaleLayer(self.rawsrc)
                layerraw.name = "Raw"
                self.layerstack.append(layerraw)


    def initAppletDrawerUi(self):
        # Load the ui file (find it in our own directory)
        localDir = os.path.split(__file__)[0]
        self._drawer = uic.loadUi(localDir+"/drawer.ui")
        self._drawer.selectFeaturesButton.pressed.connect(self._selectFeaturesButtonPressed)

    def _selectFeaturesButtonPressed(self):
        featureDict = {}
        mainOperator = self.topLevelOperatorView
        slot = mainOperator.Features
        if slot.ready():
            selectedFeatures = mainOperator.Features([]).wait()
        else:
            selectedFeatures = None

        plugins = pluginManager.getPluginsOfCategory('ObjectFeatures')

        imgshape = list(mainOperator.RawImage.meta.shape)
        axistags = mainOperator.RawImage.meta.axistags
        imgshape.pop(axistags.index('t'))
        fakeimg = np.empty(imgshape, dtype=np.float32)

        labelshape = list(mainOperator.BinaryImage.meta.shape)
        axistags = mainOperator.BinaryImage.meta.axistags
        labelshape.pop(axistags.index('t'))
        labelshape.pop(axistags.index('c') - 1)
        fakelabels = np.empty(labelshape, dtype=np.uint32)
        
        ndim = 3
        zIndex = axistags.index('z')
        if len(labelshape)==2 or (zIndex<len(mainOperator.RawImage.meta.shape) and mainOperator.RawImage.meta.shape[zIndex]==1):
            ndim=2
        
        for pluginInfo in plugins:
            featureDict[pluginInfo.name] = pluginInfo.plugin_object.availableFeatures(fakeimg, fakelabels)
        dlg = FeatureSelectionDialog(featureDict=featureDict,
                                     selectedFeatures=selectedFeatures, ndim=ndim)
        dlg.exec_()

        if dlg.result() == QDialog.Accepted:
            mainOperator.Features.setValue(dlg.selectedFeatures)
            self._calculateFeatures()

    def _calculateFeatures(self):
        mainOperator = self.topLevelOperatorView
        mainOperator.ObjectCenterImage.setDirty(SubRegion(mainOperator.ObjectCenterImage))

        maxt = mainOperator.LabelImage.meta.shape[0]
        progress = QProgressDialog("Calculating features...", "Cancel", 0, maxt)
        progress.setWindowModality(Qt.ApplicationModal)
        progress.setMinimumDuration(0)
        progress.setValue(0)

        # We will use notify_finished() to update the progress bar.
        # However, the callback will be called from a non-gui thread,
        # which cannot access gui elements directly. Therefore we use
        # this callback object to send signals back to this thread.

        # FIXME: this could probably be done much more easily with threadRouted
        class Callback(QObject):
            ndone = 0
            timestep_done = pyqtSignal(int)
            all_finished = pyqtSignal()

            def __call__(self, *args, **kwargs):
                self.ndone += 1
                self.timestep_done.emit(self.ndone)
                if self.ndone == len(reqs):
                    self.all_finished.emit()
        callback = Callback()

        def updateProgress(progress, n):
            progress.setValue(n)
        callback.timestep_done.connect(partial(updateProgress, progress))

        def finished():
            self.topLevelOperatorView._opRegFeats.fixed = True
            logger.info('Object Extraction: done.')
        callback.all_finished.connect(finished)

        mainOperator._opRegFeats.fixed = False
        reqs = []
        for t in range(maxt):
            req = mainOperator.RegionFeatures([t])
            req.submit()
            reqs.append(req)

        for i, req in enumerate(reqs):
            req.notify_finished(callback)

        # handle cancel button
        def cancel():
            for req in reqs:
                req.cancel()
        progress.canceled.connect(cancel)
Example #10
0
    def setupLayers(self):
        layers = []

        if "MergerOutput" in self.topLevelOperatorView.outputs:
            ct = colortables.create_default_8bit()
            for i in range(7):
                ct[i] = self.mergerColors[i].rgba()

            if self.topLevelOperatorView.MergerCachedOutput.ready():
                self.mergersrc = LazyflowSource(
                    self.topLevelOperatorView.MergerCachedOutput)
            else:
                self.mergersrc = LazyflowSource(
                    self.topLevelOperatorView.ZeroOutput)

            mergerLayer = ColortableLayer(self.mergersrc, ct)
            mergerLayer.name = "Merger"
            mergerLayer.visible = True
            layers.append(mergerLayer)

        ct = colortables.create_random_16bit()
        ct[0] = QColor(0, 0, 0, 0).rgba()  # make 0 transparent
        ct[1] = QColor(128, 128, 128, 255).rgba(
        )  # misdetections have id 1 and will be indicated by grey

        if self.topLevelOperatorView.CachedOutput.ready():
            self.trackingsrc = LazyflowSource(
                self.topLevelOperatorView.CachedOutput)
            trackingLayer = ColortableLayer(self.trackingsrc, ct)
            trackingLayer.name = "Tracking"
            trackingLayer.visible = True
            trackingLayer.opacity = 1.0
            layers.append(trackingLayer)
        elif self.topLevelOperatorView.zeroProvider.Output.ready():
            # provide zeros while waiting for the tracking result
            self.trackingsrc = LazyflowSource(
                self.topLevelOperatorView.zeroProvider.Output)
            trackingLayer = ColortableLayer(self.trackingsrc, ct)
            trackingLayer.name = "Tracking"
            trackingLayer.visible = True
            trackingLayer.opacity = 1.0
            layers.append(trackingLayer)

        if self.topLevelOperatorView.LabelImage.ready():
            self.objectssrc = LazyflowSource(
                self.topLevelOperatorView.LabelImage)
            ct = colortables.create_random_16bit()
            ct[0] = QColor(0, 0, 0, 0).rgba()  # make 0 transparent
            objLayer = ColortableLayer(self.objectssrc, ct)
            objLayer.name = "Objects"
            objLayer.opacity = 1.0
            objLayer.visible = True
            layers.append(objLayer)

        if self.mainOperator.RawImage.ready():
            rawLayer = self.createStandardLayerFromSlot(
                self.mainOperator.RawImage)
            rawLayer.name = "Raw"
            layers.insert(len(layers), rawLayer)

        if self.topLevelOperatorView.LabelImage.meta.shape:
            self.editor.dataShape = self.topLevelOperatorView.LabelImage.meta.shape

            maxt = self.topLevelOperatorView.LabelImage.meta.shape[0] - 1
            maxx = self.topLevelOperatorView.LabelImage.meta.shape[1] - 1
            maxy = self.topLevelOperatorView.LabelImage.meta.shape[2] - 1
            maxz = self.topLevelOperatorView.LabelImage.meta.shape[3] - 1

            if not self.mainOperator.Parameters.ready():
                raise Exception("Parameter slot is not ready")

            parameters = self.mainOperator.Parameters.value
            self._setRanges()
            if 'size_range' in parameters:
                self._drawer.to_size.setValue(parameters['size_range'][1] - 1)
                self._drawer.from_size.setValue(parameters['size_range'][0])
            else:
                self._drawer.from_size.setValue(0)
                self._drawer.to_size.setValue(10000)

            if 'x_range' in parameters:
                self._drawer.to_x.setValue(parameters['x_range'][1] - 1)
                self._drawer.from_x.setValue(parameters['x_range'][0])
            else:
                self._drawer.from_x.setValue(0)
                self._drawer.to_x.setValue(maxx)

            if 'y_range' in parameters:
                self._drawer.to_y.setValue(parameters['y_range'][1] - 1)
                self._drawer.from_y.setValue(parameters['y_range'][0])
            else:
                self._drawer.from_y.setValue(0)
                self._drawer.to_y.setValue(maxy)

            if 'z_range' in parameters:
                self._drawer.to_z.setValue(parameters['z_range'][1] - 1)
                self._drawer.from_z.setValue(parameters['z_range'][0])
            else:
                self._drawer.from_z.setValue(0)
                self._drawer.to_z.setValue(maxz)

            if 'time_range' in parameters:
                self._drawer.to_time.setValue(parameters['time_range'][1])
                self._drawer.from_time.setValue(parameters['time_range'][0])
            else:
                self._drawer.from_time.setValue(0)
                self._drawer.to_time.setValue(maxt)

            if 'scales' in parameters:
                self._drawer.x_scale.setValue(parameters['scales'][0])
                self._drawer.y_scale.setValue(parameters['scales'][1])
                self._drawer.z_scale.setValue(parameters['scales'][2])
            else:
                self._drawer.x_scale.setValue(1)
                self._drawer.y_scale.setValue(1)
                self._drawer.z_scale.setValue(1)

        return layers
Example #11
0
    def _create_rgba_layer_from_slot(cls, slot, numChannels,
                                     lastChannelIsAlpha):
        bindex = aindex = None
        rindex, gindex = 0, 1
        if numChannels > 3 or (numChannels == 3 and not lastChannelIsAlpha):
            bindex = 2
        if lastChannelIsAlpha:
            aindex = numChannels - 1

        if numChannels >= 2:
            gindex = 1
        if numChannels >= 3:
            bindex = 2
        if numChannels >= 4:
            aindex = numChannels - 1

        redSource = None
        if rindex is not None:
            redProvider = OpSingleChannelSelector(
                parent=slot.getRealOperator().parent)
            redProvider.Input.connect(slot)
            redProvider.Index.setValue(rindex)
            redSource = LazyflowSource(redProvider.Output)
            redSource.additional_owned_ops.append(redProvider)

        greenSource = None
        if gindex is not None:
            greenProvider = OpSingleChannelSelector(
                parent=slot.getRealOperator().parent)
            greenProvider.Input.connect(slot)
            greenProvider.Index.setValue(gindex)
            greenSource = LazyflowSource(greenProvider.Output)
            greenSource.additional_owned_ops.append(greenProvider)

        blueSource = None
        if bindex is not None:
            blueProvider = OpSingleChannelSelector(
                parent=slot.getRealOperator().parent)
            blueProvider.Input.connect(slot)
            blueProvider.Index.setValue(bindex)
            blueSource = LazyflowSource(blueProvider.Output)
            blueSource.additional_owned_ops.append(blueProvider)

        alphaSource = None
        if aindex is not None:
            alphaProvider = OpSingleChannelSelector(
                parent=slot.getRealOperator().parent)
            alphaProvider.Input.connect(slot)
            alphaProvider.Index.setValue(aindex)
            alphaSource = LazyflowSource(alphaProvider.Output)
            alphaSource.additional_owned_ops.append(alphaProvider)

        layer = RGBALayer(red=redSource,
                          green=greenSource,
                          blue=blueSource,
                          alpha=alphaSource)
        normalize = cls._should_normalize_display(slot)
        for i in range(4):
            if [redSource, greenSource, blueSource, alphaSource][i]:
                layer.set_range(i, slot.meta.drange)
                layer.set_normalize(i, normalize)

        return layer
    def initGraph(self):
        shape = self.inputProvider.outputs["Output"].shape
        srcs    = []
        minMax = []
        
        print "* Data has shape=%r" % (shape,)
        
        #create a layer for each channel of the input:
        slicer=OpMultiArraySlicer2(self.g)
        slicer.inputs["Input"].connect(self.inputProvider.outputs["Output"])
        
        slicer.inputs["AxisFlag"].setValue('c')
       
        nchannels = shape[-1]
        for ich in xrange(nchannels):
            if self._normalize_data:
                data=slicer.outputs['Slices'][ich][:].allocate().wait()
                #find the minimum and maximum value for normalization
                mm = (numpy.min(data), numpy.max(data))
                print "  - channel %d: min=%r, max=%r" % (ich, mm[0], mm[1])
                minMax.append(mm)
            else:
                minMax.append(None)
            layersrc = LazyflowSource(slicer.outputs['Slices'][ich], priority = 100)
            layersrc.setObjectName("raw data channel=%d" % ich)
            srcs.append(layersrc)
            
        #FIXME: we shouldn't merge channels automatically, but for now it's prettier
        layer1 = None
        if nchannels == 1:
            layer1 = GrayscaleLayer(srcs[0], normalize=minMax[0])
            layer1.set_range(0,minMax[0])
            print "  - showing raw data as grayscale"
        elif nchannels==2:
            layer1 = RGBALayer(red  = srcs[0], normalizeR=minMax[0],
                               green = srcs[1], normalizeG=minMax[1])
            layer1.set_range(0, minMax[0])
            layer1.set_range(1, minMax[1])
            print "  - showing channel 1 as red, channel 2 as green"
        elif nchannels==3:
            layer1 = RGBALayer(red   = srcs[0], normalizeR=minMax[0],
                               green = srcs[1], normalizeG=minMax[1],
                               blue  = srcs[2], normalizeB=minMax[2])
            layer1.set_range(0, minMax[0])
            layer1.set_range(1, minMax[1])
            layer1.set_range(2, minMax[2])
            print "  - showing channel 1 as red, channel 2 as green, channel 3 as blue"
        else:
            print "only 1,2 or 3 channels supported so far"
            return
        print
        
        layer1.name = "Input data"
        layer1.ref_object = None
        self.layerstack.append(layer1)
 
        self.workflow = PixelClassificationLazyflow( self.g, self.featScalesList, self.inputProvider.outputs["Output"])

        self.initLabels()
        self.startClassification()
        self.dataReadyToView.emit()
Example #13
0
    def setupLayers(self):
        """
        Called by our base class when one of our data slots has changed.
        This function creates a layer for each slot we want displayed in the volume editor.
        """
        # Base class provides the label layer.
        layers = super(PixelClassificationGui, self).setupLayers()

        ActionInfo = ShortcutManager.ActionInfo

        if ilastik_config.getboolean('ilastik', 'debug'):

            # Add the label projection layer.
            labelProjectionSlot = self.topLevelOperatorView.opLabelPipeline.opLabelArray.Projection2D
            if labelProjectionSlot.ready():
                projectionSrc = LazyflowSource(labelProjectionSlot)
                try:
                    # This colortable requires matplotlib
                    from volumina.colortables import jet
                    projectionLayer = ColortableLayer(
                        projectionSrc,
                        colorTable=[QColor(0, 0, 0, 128).rgba()] + jet(N=255),
                        normalize=(0.0, 1.0))
                except (ImportError, RuntimeError):
                    pass
                else:
                    projectionLayer.name = "Label Projection"
                    projectionLayer.visible = False
                    projectionLayer.opacity = 1.0
                    layers.append(projectionLayer)

        # Show the mask over everything except labels
        maskSlot = self.topLevelOperatorView.PredictionMasks
        if maskSlot.ready():
            maskLayer = self._create_binary_mask_layer_from_slot(maskSlot)
            maskLayer.name = "Mask"
            maskLayer.visible = True
            maskLayer.opacity = 1.0
            layers.append(maskLayer)

        # Add the uncertainty estimate layer
        uncertaintySlot = self.topLevelOperatorView.UncertaintyEstimate
        if uncertaintySlot.ready():
            uncertaintySrc = LazyflowSource(uncertaintySlot)
            uncertaintyLayer = AlphaModulatedLayer(uncertaintySrc,
                                                   tintColor=QColor(Qt.cyan),
                                                   range=(0.0, 1.0),
                                                   normalize=(0.0, 1.0))
            uncertaintyLayer.name = "Uncertainty"
            uncertaintyLayer.visible = False
            uncertaintyLayer.opacity = 1.0
            uncertaintyLayer.shortcutRegistration = (
                "u",
                ActionInfo("Prediction Layers", "Uncertainty",
                           "Show/Hide Uncertainty",
                           uncertaintyLayer.toggleVisible,
                           self.viewerControlWidget(), uncertaintyLayer))
            layers.append(uncertaintyLayer)

        labels = self.labelListData

        # Add each of the segmentations
        for channel, segmentationSlot in enumerate(
                self.topLevelOperatorView.SegmentationChannels):
            if segmentationSlot.ready() and channel < len(labels):
                ref_label = labels[channel]
                segsrc = LazyflowSource(segmentationSlot)
                segLayer = AlphaModulatedLayer(segsrc,
                                               tintColor=ref_label.pmapColor(),
                                               range=(0.0, 1.0),
                                               normalize=(0.0, 1.0))

                segLayer.opacity = 1
                segLayer.visible = False  #self.labelingDrawerUi.liveUpdateButton.isChecked()
                segLayer.visibleChanged.connect(
                    self.updateShowSegmentationCheckbox)

                def setLayerColor(c, segLayer_=segLayer, initializing=False):
                    if not initializing and segLayer_ not in self.layerstack:
                        # This layer has been removed from the layerstack already.
                        # Don't touch it.
                        return
                    segLayer_.tintColor = c
                    self._update_rendering()

                def setSegLayerName(n, segLayer_=segLayer, initializing=False):
                    if not initializing and segLayer_ not in self.layerstack:
                        # This layer has been removed from the layerstack already.
                        # Don't touch it.
                        return
                    oldname = segLayer_.name
                    newName = "Segmentation (%s)" % n
                    segLayer_.name = newName
                    if not self.render:
                        return
                    if oldname in self._renderedLayers:
                        label = self._renderedLayers.pop(oldname)
                        self._renderedLayers[newName] = label

                setSegLayerName(ref_label.name, initializing=True)

                ref_label.pmapColorChanged.connect(setLayerColor)
                ref_label.nameChanged.connect(setSegLayerName)
                #check if layer is 3d before adding the "Toggle 3D" option
                #this check is done this way to match the VolumeRenderer, in
                #case different 3d-axistags should be rendered like t-x-y
                #_axiskeys = segmentationSlot.meta.getAxisKeys()
                if len(segmentationSlot.meta.shape) == 4:
                    #the Renderer will cut out the last shape-dimension, so
                    #we're checking for 4 dimensions
                    self._setup_contexts(segLayer)
                layers.append(segLayer)

        # Add each of the predictions
        for channel, predictionSlot in enumerate(
                self.topLevelOperatorView.PredictionProbabilityChannels):
            if predictionSlot.ready() and channel < len(labels):
                ref_label = labels[channel]
                predictsrc = LazyflowSource(predictionSlot)
                predictLayer = AlphaModulatedLayer(
                    predictsrc,
                    tintColor=ref_label.pmapColor(),
                    range=(0.0, 1.0),
                    normalize=(0.0, 1.0))
                predictLayer.opacity = 0.25
                predictLayer.visible = self.labelingDrawerUi.liveUpdateButton.isChecked(
                )
                predictLayer.visibleChanged.connect(
                    self.updateShowPredictionCheckbox)

                def setLayerColor(c,
                                  predictLayer_=predictLayer,
                                  initializing=False):
                    if not initializing and predictLayer_ not in self.layerstack:
                        # This layer has been removed from the layerstack already.
                        # Don't touch it.
                        return
                    predictLayer_.tintColor = c

                def setPredLayerName(n,
                                     predictLayer_=predictLayer,
                                     initializing=False):
                    if not initializing and predictLayer_ not in self.layerstack:
                        # This layer has been removed from the layerstack already.
                        # Don't touch it.
                        return
                    newName = "Prediction for %s" % n
                    predictLayer_.name = newName

                setPredLayerName(ref_label.name, initializing=True)
                ref_label.pmapColorChanged.connect(setLayerColor)
                ref_label.nameChanged.connect(setPredLayerName)
                layers.append(predictLayer)

        # Add the raw data last (on the bottom)
        inputDataSlot = self.topLevelOperatorView.InputImages
        if inputDataSlot.ready():
            inputLayer = self.createStandardLayerFromSlot(inputDataSlot)
            inputLayer.name = "Input Data"
            inputLayer.visible = True
            inputLayer.opacity = 1.0
            # the flag window_leveling is used to determine if the contrast
            # of the layer is adjustable
            if isinstance(inputLayer, GrayscaleLayer):
                inputLayer.window_leveling = True
            else:
                inputLayer.window_leveling = False

            def toggleTopToBottom():
                index = self.layerstack.layerIndex(inputLayer)
                self.layerstack.selectRow(index)
                if index == 0:
                    self.layerstack.moveSelectedToBottom()
                else:
                    self.layerstack.moveSelectedToTop()

            inputLayer.shortcutRegistration = ("i",
                                               ActionInfo(
                                                   "Prediction Layers",
                                                   "Bring Input To Top/Bottom",
                                                   "Bring Input To Top/Bottom",
                                                   toggleTopToBottom,
                                                   self.viewerControlWidget(),
                                                   inputLayer))
            layers.append(inputLayer)

            # The thresholding button can only be used if the data is displayed as grayscale.
            if inputLayer.window_leveling:
                self.labelingDrawerUi.thresToolButton.show()
            else:
                self.labelingDrawerUi.thresToolButton.hide()

        self.handleLabelSelectionChange()
        return layers
Example #14
0
 def _create_alpha_modulated_layer_from_slot(cls, slot):
     layer = AlphaModulatedLayer(LazyflowSource(slot),
                                 tintColor=QColor(Qt.cyan),
                                 range=(0.0, 1.0),
                                 normalize=(0.0, 1.0))
     return layer
Example #15
0
class ObjectExtractionGui(LayerViewerGui):

    def stopAndCleanUp(self):
        # Unsubscribe to all signals
        for fn in self.__cleanup_fns:
            fn()

        super(ObjectExtractionGui, self).stopAndCleanUp()

    def __init__(self, *args, **kwargs):
        self.__cleanup_fns = []
        self._lock = threading.Lock()
        super( ObjectExtractionGui, self ).__init__(*args, **kwargs)

    def setupLayers(self):
        mainOperator = self.topLevelOperatorView
        layers = []

        if mainOperator.ObjectCenterImage.ready():
            self.centerimagesrc = LazyflowSource(mainOperator.ObjectCenterImage)
            redct = [0, QColor(255, 0, 0).rgba()]
            layer = ColortableLayer(self.centerimagesrc, redct)
            layer.name = "Object centers"
            layer.setToolTip("Object center positions, marked with a little red cross")
            layer.visible = False
            layers.append(layer)

        ct = colortables.create_default_16bit()
        if mainOperator.LabelImage.ready():
            self.objectssrc = LazyflowSource(mainOperator.LabelImage)
            self.objectssrc.setObjectName("LabelImage LazyflowSrc")
            ct[0] = QColor(0, 0, 0, 0).rgba() # make 0 transparent
            layer = ColortableLayer(self.objectssrc, ct)
            layer.name = "Objects (connected components)"
            layer.setToolTip("Segmented objects, shown in different colors")
            layer.visible = False
            layer.opacity = 0.5
            layers.append(layer)

        # white foreground on transparent background, even for labeled images
        binct = [QColor(255, 255, 255, 255).rgba()]*65536
        binct[0] = 0
        if mainOperator.BinaryImage.ready():
            self.binaryimagesrc = LazyflowSource(mainOperator.BinaryImage)
            self.binaryimagesrc.setObjectName("Binary LazyflowSrc")
            layer = ColortableLayer(self.binaryimagesrc, binct)
            layer.name = "Binary image"
            layer.setToolTip("Segmented objects, binary mask")
            layers.append(layer)

        ## raw data layer
        self.rawsrc = None
        self.rawsrc = LazyflowSource(mainOperator.RawImage)
        self.rawsrc.setObjectName("Raw Lazyflow Src")
        layerraw = GrayscaleLayer(self.rawsrc)
        layerraw.name = "Raw data"
        layers.insert(len(layers), layerraw)

        mainOperator.RawImage.notifyReady(self._onReady)
        self.__cleanup_fns.append( partial( mainOperator.RawImage.unregisterReady, self._onReady ) )

        mainOperator.RawImage.notifyMetaChanged(self._onMetaChanged)
        self.__cleanup_fns.append( partial( mainOperator.RawImage.unregisterMetaChanged, self._onMetaChanged ) )

        if mainOperator.BinaryImage.meta.shape:
            self.editor.dataShape = mainOperator.BinaryImage.meta.shape

        mainOperator.BinaryImage.notifyMetaChanged(self._onMetaChanged)
        self.__cleanup_fns.append( partial( mainOperator.BinaryImage.unregisterMetaChanged, self._onMetaChanged ) )

        return layers

    def _onMetaChanged(self, slot):
        #FiXME: why do we need that?
        if slot is self.topLevelOperatorView.BinaryImage:
            if slot.meta.shape:
                self.editor.dataShape = slot.meta.shape

        if slot is self.topLevelOperatorView.RawImage:
            if slot.meta.shape and not self.rawsrc:
                self.rawsrc = LazyflowSource(self.topLevelOperatorView.RawImage)
                layerraw = GrayscaleLayer(self.rawsrc)
                layerraw.name = "Raw data"
                self.layerstack.append(layerraw)

    def _onReady(self, slot):
        if slot is self.topLevelOperatorView.RawImage:
            if slot.meta.shape and not self.rawsrc:
                self.rawsrc = LazyflowSource(self.topLevelOperatorView.RawImage)
                layerraw = GrayscaleLayer(self.rawsrc)
                layerraw.name = "Raw data"
                self.layerstack.append(layerraw)


    def initAppletDrawerUi(self):
        # Load the ui file (find it in our own directory)
        localDir = os.path.split(__file__)[0]
        self._drawer = uic.loadUi(localDir+"/drawer.ui")
        self._drawer.selectFeaturesButton.pressed.connect(self._selectFeaturesButtonPressed)
        if not ilastik_config.getboolean("ilastik", "debug"):
            self._drawer.exportButton.setVisible(False)
            
        self._drawer.exportButton.pressed.connect(self._exportFeaturesButtonPressed)
        
        slot = self.topLevelOperatorView.Features
        if slot.ready():
            selectedFeatures = self.topLevelOperatorView.Features([]).wait()
        else:
            selectedFeatures = None
        
        nfeatures = 0
        if selectedFeatures is not None:
            for plugin_features in selectedFeatures.itervalues():
                nfeatures += len(plugin_features)

        self._drawer.featuresSelected.setText("{} features computed, \nsome may have multiple channels".format(nfeatures))
        
        # get the applet reference from the workflow (needed for the progressSignal)
        self.applet = self.topLevelOperatorView.parent.parent.objectExtractionApplet

    def _selectFeaturesButtonPressed(self):
        featureDict = {}
        mainOperator = self.topLevelOperatorView
        if not mainOperator.RawImage.ready():
            mexBox=QMessageBox()
            mexBox.setText("Please add the raw data before selecting features")
            mexBox.exec_()
            return
        
        if not mainOperator.BinaryImage.ready():
            mexBox=QMessageBox()
            mexBox.setText("Please add binary (segmentation) data before selecting features ")
            mexBox.exec_()
            return
        
        slot = mainOperator.Features
        if slot.ready():
            selectedFeatures = mainOperator.Features([]).wait()
        else:
            selectedFeatures = None

        plugins = pluginManager.getPluginsOfCategory('ObjectFeatures')

        taggedShape = mainOperator.RawImage.meta.getTaggedShape()
        fakeimg = None
        fakeimgshp = [taggedShape['x'], taggedShape['y']]
        fakelabelsshp = [taggedShape['x'], taggedShape['y']]
        ndim = 3
        if 'z' in taggedShape and taggedShape['z']>1:
            fakeimgshp.append(taggedShape['z'])
            fakelabelsshp.append(taggedShape['z'])
            ndim = 3
        else:
            ndim = 2
        if 'c' in taggedShape and taggedShape['c']>1:
            fakeimgshp.append(taggedShape['c'])
        
        fakeimg = np.empty(fakeimgshp, dtype=np.float32)
        fakelabels = np.empty(fakelabelsshp, dtype=np.uint32)
        
        if ndim==3:
            fakelabels = vigra.taggedView(fakelabels, 'xyz')
            if len(fakeimgshp)==4:
                fakeimg = vigra.taggedView(fakeimg, 'xyzc')
            else:
                fakeimg = vigra.taggedView(fakeimg, 'xyz')
        if ndim==2:
            fakelabels = vigra.taggedView(fakelabels, 'xy')
            if len(fakeimgshp)==3:
                fakeimg = vigra.taggedView(fakeimg, 'xyc')
            else:
                fakeimg = vigra.taggedView(fakeimg, 'xy')
        
        for pluginInfo in plugins:
            featureDict[pluginInfo.name] = pluginInfo.plugin_object.availableFeatures(fakeimg, fakelabels)
        dlg = FeatureSelectionDialog(featureDict=featureDict,
                                     selectedFeatures=selectedFeatures, ndim=ndim)
        dlg.exec_()

        if dlg.result() == QDialog.Accepted:
            mainOperator.Features.setValue(dlg.selectedFeatures)
            self._calculateFeatures()

    def _calculateFeatures(self, interactive=True):
        mainOperator = self.topLevelOperatorView
        mainOperator.ObjectCenterImage.setDirty(SubRegion(mainOperator.ObjectCenterImage))

        current_t = self.editor.posModel.time

        def _handle_all_finished(*args):
            self._lock.acquire()
            self.applet.progressSignal.emit(100)
            self.topLevelOperatorView._opRegFeats.fixed = True
            feats = self.topLevelOperatorView.RegionFeatures[0].wait()
            nfeatures = 0
            nchannels = 0

            try:
                for pname, pfeats in feats[0].iteritems():
                    if pname != 'Default features':
                        for featname, feat in pfeats.iteritems():
                            nchannels += feat.shape[1]
                            nfeatures += 1
                if interactive:
                    self._drawer.featuresSelected.setText("{} features computed, {} channels in total".format(nfeatures, nchannels))
                logger.info('Object Extraction: done.')
                success = True
            except AttributeError:
                if interactive:
                    self._drawer.featuresSelected.setText("Feature computation failed (most likely due to memory issues)")
                logger.error('Object Extraction: failed.')
                success = False

            self.applet.appletStateUpdateRequested.emit()
            self._lock.release()

        self.applet.progressSignal.emit(0)
        self.applet.progressSignal.emit(-1)

        reqs = []
        self.already_done = 0
        req = mainOperator.RegionFeatures([current_t])
        req.submit()
        req.notify_failed(self.handleFeatureComputationFailure)
        req.notify_finished(_handle_all_finished)
        reqs.append(req)

        
            

    @threadRouted
    def handleFeatureComputationFailure(self, exc, exc_info):
        import traceback
        traceback.print_tb(exc_info[2])
        msg = "Feature computation failed due to the following error:\n{}".format( exc )
        QMessageBox.critical(self, "Feature computation failed", msg)

    def _exportFeaturesButtonPressed(self):
        mainOperator = self.topLevelOperatorView
        if not mainOperator.RegionFeatures.ready():
            mexBox=QMessageBox()
            mexBox.setText("No features have been computed yet. Nothing to save.")
            mexBox.exec_()
            return
            
        fname = QFileDialog.getSaveFileName(self, caption='Export Computed Features', 
                                        filter="Pickled Objects (*.pkl);;All Files (*)")
        
        fname = encode_from_qstring( fname )
        if len(fname)>0: #not cancelled
            with open(fname, 'w') as f:
                pickle.dump(mainOperator.RegionFeatures(list()).wait(), f)
        
        
        logger.debug("Exported object features to file '{}'".format(fname))
Example #16
0
    def createStandardLayerFromSlot(cls, slot, lastChannelIsAlpha=False):
        """
        Convenience function.
        Generates a volumina layer using the given slot.
        Chooses between grayscale or RGB depending on the number of channels in the slot.

        * If *slot* has 1 channel or more than 4 channels, a GrayscaleLayer is created.
        * If *slot* has 2 non-alpha channels, an RGBALayer is created with R and G channels.
        * If *slot* has 3 non-alpha channels, an RGBALayer is created with R,G, and B channels.
        * If *slot* has 4 channels, an RGBA layer is created

        :param slot: The slot to generate a layer from
        :param lastChannelIsAlpha: If True, the last channel in the slot is assumed to be an alpha channel.
                                   If slot has 4 channels, this parameter has no effect.
        """
        def getRange(meta):
            return meta.drange

        def getNormalize(meta):
            if meta.drange is not None and meta.normalizeDisplay is False:
                # do not normalize if the user provided a range and set normalization to False
                return False
            else:
                # If we don't know the range of the data and normalization is allowed
                # by the user, create a layer that is auto-normalized.
                # See volumina.pixelpipeline.datasources for details.
                #
                # Even in the case of integer data, which has more than 255 possible values,
                # (like uint16), it seems reasonable to use this setting as default
                return None  # means autoNormalize

        shape = slot.meta.shape

        try:
            channelAxisIndex = slot.meta.axistags.index('c')
            #assert channelAxisIndex < len(slot.meta.axistags), \
            #    "slot %s has shape = %r, axistags = %r, but no channel dimension" \
            #    % (slot.name, slot.meta.shape, slot.meta.axistags)
            numChannels = shape[channelAxisIndex]
            axisinfo = slot.meta.axistags["c"].description
        except:
            numChannels = 1
            axisinfo = ""  # == no info on channels given

        rindex = None
        bindex = None
        gindex = None
        aindex = None

        if axisinfo == "" or axisinfo == "default":
            # Examine channel dimension to determine Grayscale vs. RGB

            if numChannels == 4:
                lastChannelIsAlpha = True

            if lastChannelIsAlpha:
                assert numChannels <= 4, "Can't display a standard layer with more than four channels (with alpha).  Your image has {} channels.".format(
                    numChannels)

            if numChannels == 1 or (numChannels > 4):
                assert not lastChannelIsAlpha, "Can't have an alpha channel if there is no color channel"
                source = LazyflowSource(slot)
                layer = GrayscaleLayer(source)
                layer.numberOfChannels = numChannels
                normalize = getNormalize(slot.meta)
                range = getRange(slot.meta)
                layer.set_range(0, range)
                layer.set_normalize(0, normalize)
                return layer

            assert numChannels > 2 or (numChannels == 2 and not lastChannelIsAlpha), \
                "Unhandled combination of channels.  numChannels={}, lastChannelIsAlpha={}, axistags={}".format( numChannels, lastChannelIsAlpha, slot.meta.axistags )

            rindex = 0
            gindex = 1
            if numChannels > 3 or (numChannels == 3
                                   and not lastChannelIsAlpha):
                bindex = 2
            if lastChannelIsAlpha:
                aindex = numChannels - 1

        elif axisinfo == "grayscale":
            source = LazyflowSource(slot)
            layer = GrayscaleLayer(source)
            layer.numberOfChannels = numChannels
            normalize = getNormalize(slot.meta)
            range = getRange(slot.meta)
            layer.set_range(0, range)
            layer.set_normalize(0, normalize)
            return layer

        elif axisinfo == "rgba":
            rindex = 0
            if numChannels >= 2:
                gindex = 1
            if numChannels >= 3:
                bindex = 2
            if numChannels >= 4:
                aindex = numChannels - 1
        else:
            raise RuntimeError("unknown channel display mode")

        redSource = None
        if rindex is not None:
            redProvider = OpSingleChannelSelector(
                parent=slot.getRealOperator().parent)
            redProvider.Input.connect(slot)
            redProvider.Index.setValue(rindex)
            redSource = LazyflowSource(redProvider.Output)
            redSource.additional_owned_ops.append(redProvider)

        greenSource = None
        if gindex is not None:
            greenProvider = OpSingleChannelSelector(
                parent=slot.getRealOperator().parent)
            greenProvider.Input.connect(slot)
            greenProvider.Index.setValue(gindex)
            greenSource = LazyflowSource(greenProvider.Output)
            greenSource.additional_owned_ops.append(greenProvider)

        blueSource = None
        if bindex is not None:
            blueProvider = OpSingleChannelSelector(
                parent=slot.getRealOperator().parent)
            blueProvider.Input.connect(slot)
            blueProvider.Index.setValue(bindex)
            blueSource = LazyflowSource(blueProvider.Output)
            blueSource.additional_owned_ops.append(blueProvider)

        alphaSource = None
        if aindex is not None:
            alphaProvider = OpSingleChannelSelector(
                parent=slot.getRealOperator().parent)
            alphaProvider.Input.connect(slot)
            alphaProvider.Index.setValue(aindex)
            alphaSource = LazyflowSource(alphaProvider.Output)
            alphaSource.additional_owned_ops.append(alphaProvider)

        layer = RGBALayer(red=redSource,
                          green=greenSource,
                          blue=blueSource,
                          alpha=alphaSource)

        normalize = getNormalize(slot.meta)
        range = getRange(slot.meta)
        for i in xrange(4):
            if [redSource, greenSource, blueSource, alphaSource][i]:
                layer.set_range(i, range)
                layer.set_normalize(i, normalize)

        return layer
class ObjectExtractionGui(QWidget):

    ###########################################
    ### AppletGuiInterface Concrete Methods ###
    ###########################################

    def centralWidget(self):
        """ Return the widget that will be displayed in the main viewer area. """
        return self.volumeEditorWidget

    def appletDrawer(self):
        return self._drawer

    def menus(self):
        return []

    def viewerControlWidget(self):
        return self._viewerControlWidget

    def stopAndCleanUp(self):
        pass

    ###########################################
    ###########################################

    def __init__(self, topLevelOperatorView):
        super(ObjectExtractionGui, self).__init__()
        self.mainOperator = topLevelOperatorView
        self.layerstack = LayerStackModel()

        self._viewerControlWidget = None
        self._initViewerControlUi()

        self.editor = None
        self._initEditor()

        self._initAppletDrawerUi()
        assert(self.appletDrawer() is not None)
        self._initViewer()

    def _onMetaChanged(self, slot):
        if slot is self.mainOperator.BinaryImage:
            if slot.meta.shape:
                self.editor.dataShape = slot.meta.shape

        if slot is self.mainOperator.RawImage:
            if slot.meta.shape and not self.rawsrc:
                self.rawsrc = LazyflowSource(self.mainOperator.RawImage)
                layerraw = GrayscaleLayer(self.rawsrc)
                layerraw.name = "Raw"
                self.layerstack.append(layerraw)

    def _onReady(self, slot):
        if slot is self.mainOperator.RawImage:
            if slot.meta.shape and not self.rawsrc:
                self.rawsrc = LazyflowSource(self.mainOperator.RawImage)
                layerraw = GrayscaleLayer(self.rawsrc)
                layerraw.name = "Raw"
                self.layerstack.append(layerraw)

    def _initViewer(self):
        mainOperator = self.mainOperator

        # white foreground on transparent background
        ct = [QColor(0, 0, 0, 0).rgba(),
              QColor(255, 255, 255, 255).rgba()]
        self.binaryimagesrc = LazyflowSource(mainOperator.BinaryImage)
        self.binaryimagesrc.setObjectName("Binary LazyflowSrc")
        layer = ColortableLayer(self.binaryimagesrc, ct)
        layer.name = "Binary Image"
        self.layerstack.append(layer)

        ct = colortables.create_default_16bit()
        self.objectssrc = LazyflowSource(mainOperator.LabelImage)
        self.objectssrc.setObjectName("LabelImage LazyflowSrc")
        ct[0] = QColor(0, 0, 0, 0).rgba() # make 0 transparent
        layer = ColortableLayer(self.objectssrc, ct)
        layer.name = "Label Image"
        layer.visible = False
        layer.opacity = 0.5
        self.layerstack.append(layer)

        self.centerimagesrc = LazyflowSource(mainOperator.ObjectCenterImage)
        layer = RGBALayer(red=ConstantSource(255), alpha=self.centerimagesrc)
        layer.name = "Object Centers"
        layer.visible = False
        self.layerstack.append(layer)

        ## raw data layer
        self.rawsrc = None
        self.rawsrc = LazyflowSource(self.mainOperator.RawImage)
        self.rawsrc.setObjectName("Raw Lazyflow Src")
        layerraw = GrayscaleLayer(self.rawsrc)
        layerraw.name = "Raw"
        self.layerstack.insert(len(self.layerstack), layerraw)

        mainOperator.RawImage.notifyReady(self._onReady)
        mainOperator.RawImage.notifyMetaChanged(self._onMetaChanged)

        if mainOperator.BinaryImage.meta.shape:
            self.editor.dataShape = mainOperator.BinaryImage.meta.shape
        mainOperator.BinaryImage.notifyMetaChanged(self._onMetaChanged)

    def _initEditor(self):
        """Initialize the Volume Editor GUI."""

        self.editor = VolumeEditor(self.layerstack, crosshair=False)

        self.volumeEditorWidget = VolumeEditorWidget()
        self.volumeEditorWidget.init(self.editor)

        # The editor's layerstack is in charge of which layer movement buttons are enabled
        model = self.editor.layerStack
        self._viewerControlWidget.setupConnections(model)

        self.editor._lastImageViewFocus = 0

    def _initAppletDrawerUi(self):
        # Load the ui file (find it in our own directory)
        localDir = os.path.split(__file__)[0]
        self._drawer = uic.loadUi(localDir+"/drawer.ui")

        self._drawer.selectFeaturesButton.pressed.connect(self._selectFeaturesButtonPressed)

    def _initViewerControlUi(self):
        self._viewerControlWidget = ViewerControls(self)

    def _selectFeaturesButtonPressed(self):
        featureDict = {}
        slot = self.mainOperator.Features
        if slot.ready():
            selectedFeatures = self.mainOperator.Features([]).wait()
        else:
            selectedFeatures = None

        try:
            plugins = pluginManager.getPluginsOfCategory('ObjectFeatures')
        except:
            QMessageBox.warning(self,
                                'object features unavailable',
                                'Object features plugins failed. Perhaps Yapsy is not installed?',
                                QMessageBox.Ok)
            return

        imgshape = list(self.mainOperator.RawImage.meta.shape)
        axistags = self.mainOperator.RawImage.meta.axistags
        imgshape.pop(axistags.index('t'))
        fakeimg = np.empty(imgshape, dtype=np.float32)

        labelshape = list(self.mainOperator.BinaryImage.meta.shape)
        axistags = self.mainOperator.BinaryImage.meta.axistags
        labelshape.pop(axistags.index('t'))
        labelshape.pop(axistags.index('c') - 1)
        fakelabels = np.empty(labelshape, dtype=np.uint32)

        for pluginInfo in plugins:
            featureDict[pluginInfo.name] = pluginInfo.plugin_object.availableFeatures(fakeimg, fakelabels)
        dlg = FeatureSelectionDialog(featureDict=featureDict,
                                     selectedFeatures=selectedFeatures)
        dlg.exec_()

        if dlg.result() == QDialog.Accepted:
            self.mainOperator.Features.setValue(dlg.selectedFeatures)
            self._calculateFeatures()

    def _calculateFeatures(self):
        self.mainOperator.ObjectCenterImage.setDirty(SubRegion(self.mainOperator.ObjectCenterImage))

        maxt = self.mainOperator.LabelImage.meta.shape[0]
        progress = QProgressDialog("Calculating features...", "Cancel", 0, maxt)
        progress.setWindowModality(Qt.ApplicationModal)
        progress.setMinimumDuration(0)
        progress.setValue(0)

        # We will use notify_finished() to update the progress bar.
        # However, the callback will be called from a non-gui thread,
        # which cannot access gui elements directly. Therefore we use
        # this callback object to send signals back to this thread.
        class Callback(QObject):
            ndone = 0
            timestep_done = pyqtSignal(int)
            all_finished = pyqtSignal()

            def __call__(self, *args, **kwargs):
                self.ndone += 1
                self.timestep_done.emit(self.ndone)
                if self.ndone == len(reqs):
                    self.all_finished.emit()
        callback = Callback()

        def updateProgress(progress, n):
            progress.setValue(n)
        callback.timestep_done.connect(partial(updateProgress, progress))

        def finished():
            self.mainOperator._opRegFeats.fixed = True
            print 'Object Extraction: done.'
        callback.all_finished.connect(finished)

        self.mainOperator._opRegFeats.fixed = False
        reqs = []
        for t in range(maxt):
            req = self.mainOperator.RegionFeatures([t])
            req.submit()
            reqs.append(req)

        for i, req in enumerate(reqs):
            req.notify_finished(callback)

        # handle cancel button
        def cancel():
            for req in reqs:
                req.cancel()
        progress.canceled.connect(cancel)
Example #18
0
    def setupLayers(self):
        layers = []

        opLane = self.topLevelOperatorView

        selection_names = opLane.SelectionNames.value
        selection = selection_names[opLane.InputSelection.value]

        # This code is written to handle the specific output cases we know about.
        # If those change, update this function!
        assert selection in [
            'Object Predictions', 'Object Probabilities',
            'Blockwise Object Predictions', 'Blockwise Object Probabilities',
            'Pixel Probabilities'
        ]

        if selection in ("Object Predictions", "Blockwise Object Predictions"):
            fromDiskSlot = self.topLevelOperatorView.ImageOnDisk
            if fromDiskSlot.ready():
                exportLayer = ColortableLayer(LazyflowSource(fromDiskSlot),
                                              colorTable=self._colorTable16)
                exportLayer.name = "Prediction - Exported"
                exportLayer.visible = True
                layers.append(exportLayer)

            previewSlot = self.topLevelOperatorView.ImageToExport
            if previewSlot.ready():
                previewLayer = ColortableLayer(LazyflowSource(previewSlot),
                                               colorTable=self._colorTable16)
                previewLayer.name = "Prediction - Preview"
                previewLayer.visible = False
                layers.append(previewLayer)

        elif selection in ("Object Probabilities",
                           "Blockwise Object Probabilities"):
            exportedLayers = self._initPredictionLayers(opLane.ImageOnDisk)
            for layer in exportedLayers:
                layer.visible = True
                layer.name = layer.name + "- Exported"
            layers += exportedLayers

            previewLayers = self._initPredictionLayers(opLane.ImageToExport)
            for layer in previewLayers:
                layer.visible = False
                layer.name = layer.name + "- Preview"
            layers += previewLayers

        elif selection == 'Pixel Probabilities':
            exportedLayers = self._initPredictionLayers(opLane.ImageOnDisk)
            for layer in exportedLayers:
                layer.visible = True
                layer.name = layer.name + "- Exported"
            layers += exportedLayers

            previewLayers = self._initPredictionLayers(opLane.ImageToExport)
            for layer in previewLayers:
                layer.visible = False
                layer.name = layer.name + "- Preview"
            layers += previewLayers
        else:
            assert False, "Unknown selection."

        rawSlot = self.topLevelOperatorView.RawData
        if rawSlot.ready():
            rawLayer = self.createStandardLayerFromSlot(rawSlot)
            rawLayer.name = "Raw Data"
            rawLayer.opacity = 1.0
            layers.append(rawLayer)

        return layers
Example #19
0
    def setupLayers(self):
        layers = []

        # use same colortable for the following two generated layers: the merger
        # and the tracking layer
        self.tracking_colortable = colortables.create_random_16bit()
        self.tracking_colortable[0] = QColor(0, 0, 0,
                                             0).rgba()  # make 0 transparent
        self.tracking_colortable[1] = QColor(128, 128, 128, 255).rgba(
        )  # misdetections have id 1 and will be indicated by grey

        self.merger_colortable = colortables.create_default_16bit()
        for i in range(7):
            self.merger_colortable[i] = self.mergerColors[i].rgba()

        if "MergerOutput" in self.topLevelOperatorView.outputs:
            parameters = self.mainOperator.Parameters.value

            if 'withMergerResolution' in parameters.keys(
            ) and not parameters['withMergerResolution']:
                merger_ct = self.merger_colortable
            else:
                merger_ct = self.tracking_colortable

            # Using same color table for tracking with and without mergers (Is there any reason for using different color tables?)
            merger_ct = self.tracking_colortable

            if self.topLevelOperatorView.MergerCachedOutput.ready():
                self.mergersrc = LazyflowSource(
                    self.topLevelOperatorView.MergerCachedOutput)
            else:
                self.mergersrc = LazyflowSource(
                    self.topLevelOperatorView.zeroProvider.Output)

            mergerLayer = ColortableLayer(self.mergersrc, merger_ct)
            mergerLayer.name = "Merger"

            if 'withMergerResolution' in parameters.keys(
            ) and not parameters['withMergerResolution']:
                mergerLayer.visible = True
            else:
                mergerLayer.visible = False

            layers.append(mergerLayer)

        if self.topLevelOperatorView.CachedOutput.ready():
            self.trackingsrc = LazyflowSource(
                self.topLevelOperatorView.CachedOutput)
            trackingLayer = ColortableLayer(self.trackingsrc,
                                            self.tracking_colortable)
            trackingLayer.name = "Tracking"
            trackingLayer.visible = True
            trackingLayer.opacity = 1.0
            layers.append(trackingLayer)

        elif self.topLevelOperatorView.zeroProvider.Output.ready():
            # provide zeros while waiting for the tracking result
            self.trackingsrc = LazyflowSource(
                self.topLevelOperatorView.zeroProvider.Output)
            trackingLayer = ColortableLayer(self.trackingsrc,
                                            self.tracking_colortable)
            trackingLayer.name = "Tracking"
            trackingLayer.visible = True
            trackingLayer.opacity = 1.0
            layers.append(trackingLayer)

        if "RelabeledImage" in self.topLevelOperatorView.outputs:
            if self.topLevelOperatorView.RelabeledCachedOutput.ready():
                self.objectssrc = LazyflowSource(
                    self.topLevelOperatorView.RelabeledCachedOutput)
            else:
                self.objectssrc = LazyflowSource(
                    self.topLevelOperatorView.zeroProvider.Output)
        else:
            if self.topLevelOperatorView.LabelImage.ready():
                self.objectssrc = LazyflowSource(
                    self.topLevelOperatorView.LabelImage)
        ct = colortables.create_random_16bit()
        ct[0] = QColor(0, 0, 0, 0).rgba()  # make 0 transparent
        objLayer = ColortableLayer(self.objectssrc, ct)
        objLayer.name = "Objects"
        objLayer.opacity = 1.0
        objLayer.visible = False
        layers.append(objLayer)

        if self.mainOperator.RawImage.ready():
            rawLayer = self.createStandardLayerFromSlot(
                self.mainOperator.RawImage)
            rawLayer.name = "Raw"
            layers.insert(len(layers), rawLayer)

        if self.topLevelOperatorView.LabelImage.meta.shape:
            maxt = self.topLevelOperatorView.LabelImage.meta.shape[0] - 1
            maxx = self.topLevelOperatorView.LabelImage.meta.shape[1] - 1
            maxy = self.topLevelOperatorView.LabelImage.meta.shape[2] - 1
            maxz = self.topLevelOperatorView.LabelImage.meta.shape[3] - 1

            if not self.mainOperator.Parameters.ready():
                raise Exception("Parameter slot is not ready")

            parameters = self.mainOperator.Parameters.value
            self._setRanges()
            if 'size_range' in parameters:
                self._drawer.to_size.setValue(parameters['size_range'][1] - 1)
                self._drawer.from_size.setValue(parameters['size_range'][0])
            else:
                self._drawer.from_size.setValue(0)
                self._drawer.to_size.setValue(10000)

            if 'x_range' in parameters:
                self._drawer.to_x.setValue(parameters['x_range'][1] - 1)
                self._drawer.from_x.setValue(parameters['x_range'][0])
            else:
                self._drawer.from_x.setValue(0)
                self._drawer.to_x.setValue(maxx)

            if 'y_range' in parameters:
                self._drawer.to_y.setValue(parameters['y_range'][1] - 1)
                self._drawer.from_y.setValue(parameters['y_range'][0])
            else:
                self._drawer.from_y.setValue(0)
                self._drawer.to_y.setValue(maxy)

            if 'z_range' in parameters:
                self._drawer.to_z.setValue(parameters['z_range'][1] - 1)
                self._drawer.from_z.setValue(parameters['z_range'][0])
            else:
                self._drawer.from_z.setValue(0)
                self._drawer.to_z.setValue(maxz)

            if 'time_range' in parameters:
                self._drawer.to_time.setValue(parameters['time_range'][1])
                self._drawer.from_time.setValue(parameters['time_range'][0])
            else:
                self._drawer.from_time.setValue(0)
                self._drawer.to_time.setValue(maxt)

            if 'scales' in parameters:
                self._drawer.x_scale.setValue(parameters['scales'][0])
                self._drawer.y_scale.setValue(parameters['scales'][1])
                self._drawer.z_scale.setValue(parameters['scales'][2])
            else:
                self._drawer.x_scale.setValue(1)
                self._drawer.y_scale.setValue(1)
                self._drawer.z_scale.setValue(1)

        return layers
Example #20
0
    def setupLayers(self):
        mainOperator = self.topLevelOperatorView
        layers = []

        if mainOperator.ObjectCenterImage.ready():
            self.centerimagesrc = LazyflowSource(
                mainOperator.ObjectCenterImage)
            redct = [0, QColor(255, 0, 0).rgba()]
            layer = ColortableLayer(self.centerimagesrc, redct)
            layer.name = "Object centers"
            layer.setToolTip(
                "Object center positions, marked with a little red cross")
            layer.visible = False
            layers.append(layer)

        ct = colortables.create_default_16bit()
        if mainOperator.LabelImage.ready():
            self.objectssrc = LazyflowSource(mainOperator.LabelImage)
            self.objectssrc.setObjectName("LabelImage LazyflowSrc")
            ct[0] = QColor(0, 0, 0, 0).rgba()  # make 0 transparent
            layer = ColortableLayer(self.objectssrc, ct)
            layer.name = "Objects (connected components)"
            layer.setToolTip("Segmented objects, shown in different colors")
            layer.visible = False
            layer.opacity = 0.5
            layers.append(layer)

        # white foreground on transparent background, even for labeled images
        binct = [QColor(255, 255, 255, 255).rgba()] * 65536
        binct[0] = 0
        if mainOperator.BinaryImage.ready():
            self.binaryimagesrc = LazyflowSource(mainOperator.BinaryImage)
            self.binaryimagesrc.setObjectName("Binary LazyflowSrc")
            layer = ColortableLayer(self.binaryimagesrc, binct)
            layer.name = "Binary image"
            layer.setToolTip("Segmented objects, binary mask")
            layers.append(layer)

        ## raw data layer
        self.rawsrc = None
        self.rawsrc = LazyflowSource(mainOperator.RawImage)
        self.rawsrc.setObjectName("Raw Lazyflow Src")
        layerraw = GrayscaleLayer(self.rawsrc)
        layerraw.name = "Raw data"
        layers.insert(len(layers), layerraw)

        mainOperator.RawImage.notifyReady(self._onReady)
        self.__cleanup_fns.append(
            partial(mainOperator.RawImage.unregisterReady, self._onReady))

        mainOperator.RawImage.notifyMetaChanged(self._onMetaChanged)
        self.__cleanup_fns.append(
            partial(mainOperator.RawImage.unregisterMetaChanged,
                    self._onMetaChanged))

        mainOperator.BinaryImage.notifyMetaChanged(self._onMetaChanged)
        self.__cleanup_fns.append(
            partial(mainOperator.BinaryImage.unregisterMetaChanged,
                    self._onMetaChanged))

        return layers
Example #21
0
class ObjectExtractionGui(LayerViewerGui):
    def stopAndCleanUp(self):
        # Unsubscribe to all signals
        for fn in self.__cleanup_fns:
            fn()

        super(ObjectExtractionGui, self).stopAndCleanUp()

    def __init__(self, *args, **kwargs):
        self.__cleanup_fns = []
        self._lock = threading.Lock()
        super(ObjectExtractionGui, self).__init__(*args, **kwargs)

    def setupLayers(self):
        mainOperator = self.topLevelOperatorView
        layers = []

        if mainOperator.ObjectCenterImage.ready():
            self.centerimagesrc = LazyflowSource(
                mainOperator.ObjectCenterImage)
            redct = [0, QColor(255, 0, 0).rgba()]
            layer = ColortableLayer(self.centerimagesrc, redct)
            layer.name = "Object centers"
            layer.setToolTip(
                "Object center positions, marked with a little red cross")
            layer.visible = False
            layers.append(layer)

        ct = colortables.create_default_16bit()
        if mainOperator.LabelImage.ready():
            self.objectssrc = LazyflowSource(mainOperator.LabelImage)
            self.objectssrc.setObjectName("LabelImage LazyflowSrc")
            ct[0] = QColor(0, 0, 0, 0).rgba()  # make 0 transparent
            layer = ColortableLayer(self.objectssrc, ct)
            layer.name = "Objects (connected components)"
            layer.setToolTip("Segmented objects, shown in different colors")
            layer.visible = False
            layer.opacity = 0.5
            layers.append(layer)

        # white foreground on transparent background, even for labeled images
        binct = [QColor(255, 255, 255, 255).rgba()] * 65536
        binct[0] = 0
        if mainOperator.BinaryImage.ready():
            self.binaryimagesrc = LazyflowSource(mainOperator.BinaryImage)
            self.binaryimagesrc.setObjectName("Binary LazyflowSrc")
            layer = ColortableLayer(self.binaryimagesrc, binct)
            layer.name = "Binary image"
            layer.setToolTip("Segmented objects, binary mask")
            layers.append(layer)

        ## raw data layer
        self.rawsrc = None
        self.rawsrc = LazyflowSource(mainOperator.RawImage)
        self.rawsrc.setObjectName("Raw Lazyflow Src")
        layerraw = GrayscaleLayer(self.rawsrc)
        layerraw.name = "Raw data"
        layers.insert(len(layers), layerraw)

        mainOperator.RawImage.notifyReady(self._onReady)
        self.__cleanup_fns.append(
            partial(mainOperator.RawImage.unregisterReady, self._onReady))

        mainOperator.RawImage.notifyMetaChanged(self._onMetaChanged)
        self.__cleanup_fns.append(
            partial(mainOperator.RawImage.unregisterMetaChanged,
                    self._onMetaChanged))

        mainOperator.BinaryImage.notifyMetaChanged(self._onMetaChanged)
        self.__cleanup_fns.append(
            partial(mainOperator.BinaryImage.unregisterMetaChanged,
                    self._onMetaChanged))

        return layers

    def _onMetaChanged(self, slot):
        #FiXME: why do we need that?
        if slot is self.topLevelOperatorView.BinaryImage:
            if slot.meta.shape:
                self.editor.dataShape = slot.meta.shape

        if slot is self.topLevelOperatorView.RawImage:
            if slot.meta.shape and not self.rawsrc:
                self.rawsrc = LazyflowSource(
                    self.topLevelOperatorView.RawImage)
                layerraw = GrayscaleLayer(self.rawsrc)
                layerraw.name = "Raw data"
                self.layerstack.append(layerraw)

    def _onReady(self, slot):
        if slot is self.topLevelOperatorView.RawImage:
            if slot.meta.shape and not self.rawsrc:
                self.rawsrc = LazyflowSource(
                    self.topLevelOperatorView.RawImage)
                layerraw = GrayscaleLayer(self.rawsrc)
                layerraw.name = "Raw data"
                self.layerstack.append(layerraw)

    def initAppletDrawerUi(self):
        # Load the ui file (find it in our own directory)
        localDir = os.path.split(__file__)[0]
        self._drawer = uic.loadUi(localDir + "/drawer.ui")
        self._drawer.selectFeaturesButton.pressed.connect(
            self._selectFeaturesButtonPressed)
        if not ilastik_config.getboolean("ilastik", "debug"):
            self._drawer.exportButton.setVisible(False)

        self._drawer.exportButton.pressed.connect(
            self._exportFeaturesButtonPressed)

        slot = self.topLevelOperatorView.Features
        if slot.ready():
            selectedFeatures = self.topLevelOperatorView.Features([]).wait()
        else:
            selectedFeatures = None

        nfeatures = 0
        if selectedFeatures is not None:
            for plugin_features in selectedFeatures.values():
                nfeatures += len(plugin_features)

        self._drawer.featuresSelected.setText(
            "{} features computed, \nsome may have multiple channels".format(
                nfeatures))

        # get the applet reference from the workflow (needed for the progressSignal)
        self.applet = self.topLevelOperatorView.parent.parent.objectExtractionApplet

    def _selectFeaturesButtonPressed(self):
        featureDict = {}
        mainOperator = self.topLevelOperatorView
        if not mainOperator.RawImage.ready():
            mexBox = QMessageBox()
            mexBox.setText("Please add the raw data before selecting features")
            mexBox.exec_()
            return

        if not mainOperator.BinaryImage.ready():
            mexBox = QMessageBox()
            mexBox.setText(
                "Please add binary (segmentation) data before selecting features "
            )
            mexBox.exec_()
            return

        slot = mainOperator.Features
        if slot.ready():
            selectedFeatures = mainOperator.Features([]).wait()
        else:
            selectedFeatures = None

        plugins = pluginManager.getPluginsOfCategory('ObjectFeatures')
        taggedShape = mainOperator.RawImage.meta.getTaggedShape()
        fakeimgshp = [taggedShape['x'], taggedShape['y']]
        fakelabelsshp = [taggedShape['x'], taggedShape['y']]
        ndim = 3
        if 'z' in taggedShape and taggedShape['z'] > 1:
            fakeimgshp.append(taggedShape['z'])
            fakelabelsshp.append(taggedShape['z'])
            ndim = 3
        else:
            ndim = 2
        if 'c' in taggedShape and taggedShape['c'] > 1:
            fakeimgshp.append(taggedShape['c'])

        fakeimg = numpy.empty(fakeimgshp, dtype=numpy.float32)
        fakelabels = numpy.empty(fakelabelsshp, dtype=numpy.uint32)

        if ndim == 3:
            fakelabels = vigra.taggedView(fakelabels, 'xyz')
            if len(fakeimgshp) == 4:
                fakeimg = vigra.taggedView(fakeimg, 'xyzc')
            else:
                fakeimg = vigra.taggedView(fakeimg, 'xyz')
        if ndim == 2:
            fakelabels = vigra.taggedView(fakelabels, 'xy')
            if len(fakeimgshp) == 3:
                fakeimg = vigra.taggedView(fakeimg, 'xyc')
            else:
                fakeimg = vigra.taggedView(fakeimg, 'xy')

        for pluginInfo in plugins:
            availableFeatures = pluginInfo.plugin_object.availableFeatures(
                fakeimg, fakelabels)
            if len(availableFeatures) > 0:
                featureDict[pluginInfo.name] = availableFeatures

        # Make sure no plugins use the same feature names.
        # (Currently, our feature export implementation doesn't support repeated column names.)
        all_feature_names = chain(*[
            list(plugin_dict.keys())
            for plugin_dict in list(featureDict.values())
        ])
        feature_set = set()
        for name in all_feature_names:
            assert name not in feature_set, \
                "Feature name '{}' is used by more than one feature plugin.\n"\
                "All plugins must produce uniquely named features.\n"\
                "The plugins and feature names we found are:\n{}"\
                .format(name, featureDict)
            feature_set.add(name)

        dlg = FeatureSelectionDialog(featureDict=featureDict,
                                     selectedFeatures=selectedFeatures,
                                     ndim=ndim)
        dlg.exec_()

        if dlg.result() == QDialog.Accepted:
            mainOperator.Features.setValue(dlg.selectedFeatures)
            self._calculateFeatures()

    def _calculateFeatures(self, interactive=True):
        mainOperator = self.topLevelOperatorView
        mainOperator.ObjectCenterImage.setDirty(
            SubRegion(mainOperator.ObjectCenterImage))

        current_t = self.editor.posModel.time

        def _handle_all_finished(*args):
            self._lock.acquire()
            self.applet.progressSignal(100)
            self.topLevelOperatorView._opRegFeats.fixed = True
            feats = self.topLevelOperatorView.RegionFeatures[0].wait()
            nfeatures = 0
            nchannels = 0

            try:
                for pname, pfeats in feats[0].items():
                    if pname != default_features_key:
                        for featname, feat in pfeats.items():
                            nchannels += feat.shape[1]
                            nfeatures += 1
                if interactive:
                    self._drawer.featuresSelected.setText(
                        "{} features computed, {} channels in total".format(
                            nfeatures, nchannels))
                logger.info('Object Extraction: done.')
                success = True
            except AttributeError:
                if interactive:
                    self._drawer.featuresSelected.setText(
                        "Feature computation failed (most likely due to memory issues)"
                    )
                logger.error('Object Extraction: failed.')
                success = False

            self.applet.appletStateUpdateRequested()
            self._lock.release()

        self.applet.progressSignal(0)
        self.applet.progressSignal(-1)

        reqs = []
        self.already_done = 0
        req = mainOperator.RegionFeatures([current_t])
        req.submit()
        req.notify_failed(self.handleFeatureComputationFailure)
        req.notify_finished(_handle_all_finished)
        reqs.append(req)

    @threadRouted
    def handleFeatureComputationFailure(self, exc, exc_info):
        msg = "Feature computation failed due to the following error:\n{}".format(
            exc)
        log_exception(logger, msg, exc_info)
        QMessageBox.critical(self, "Feature computation failed", msg)

    def _exportFeaturesButtonPressed(self):
        mainOperator = self.topLevelOperatorView
        if not mainOperator.RegionFeatures.ready():
            mexBox = QMessageBox()
            mexBox.setText(
                "No features have been computed yet. Nothing to save.")
            mexBox.exec_()
            return

        fname, _filter = QFileDialog.getSaveFileName(
            self,
            caption='Export Computed Features',
            filter="Pickled Objects (*.pkl);;All Files (*)")

        if len(fname) > 0:  #not cancelled
            with open(fname, 'w') as f:
                pickle.dump(mainOperator.RegionFeatures(list()).wait(), f, 0)

        logger.debug("Exported object features to file '{}'".format(fname))
Example #22
0
    def setupLayers(self):

        # Base class provides the label layer.
        layers = super(ObjectClassificationGui, self).setupLayers()

        binarySlot = self.op.BinaryImages
        segmentedSlot = self.op.SegmentationImages
        rawSlot = self.op.RawImages

        #This is just for colors
        labels = self.labelListData

        for channel, probSlot in enumerate(
                self.op.PredictionProbabilityChannels):
            if probSlot.ready() and channel < len(labels):
                ref_label = labels[channel]
                probsrc = LazyflowSource(probSlot)
                probLayer = AlphaModulatedLayer(
                    probsrc,
                    tintColor=ref_label.pmapColor(),
                    range=(0.0, 1.0),
                    normalize=(0.0, 1.0))
                probLayer.opacity = 0.25
                #probLayer.visible = self.labelingDrawerUi.checkInteractive.isChecked()
                #False, because it's much faster to draw predictions without these layers below
                probLayer.visible = False
                probLayer.setToolTip(
                    "Probability that the object belongs to class {}".format(
                        channel + 1))

                def setLayerColor(c,
                                  predictLayer_=probLayer,
                                  ch=channel,
                                  initializing=False):
                    if not initializing and predictLayer_ not in self.layerstack:
                        # This layer has been removed from the layerstack already.
                        # Don't touch it.
                        return
                    predictLayer_.tintColor = c

                def setLayerName(n,
                                 predictLayer_=probLayer,
                                 initializing=False):
                    if not initializing and predictLayer_ not in self.layerstack:
                        # This layer has been removed from the layerstack already.
                        # Don't touch it.
                        return
                    newName = "Prediction for %s" % n
                    predictLayer_.name = newName

                setLayerName(ref_label.name, initializing=True)
                ref_label.pmapColorChanged.connect(setLayerColor)
                ref_label.nameChanged.connect(setLayerName)
                layers.append(probLayer)

        predictionSlot = self.op.PredictionImages
        if predictionSlot.ready():
            predictsrc = LazyflowSource(predictionSlot)
            self._colorTable16_forpmaps[0] = 0
            predictLayer = ColortableLayer(
                predictsrc, colorTable=self._colorTable16_forpmaps)

            predictLayer.name = self.PREDICTION_LAYER_NAME
            predictLayer.ref_object = None
            predictLayer.visible = self.labelingDrawerUi.checkInteractive.isChecked(
            )
            predictLayer.opacity = 0.5
            predictLayer.setToolTip(
                "Classification results, assigning a label to each object")

            # This weakref stuff is a little more fancy than strictly necessary.
            # The idea is to use the weakref's callback to determine when this layer instance is destroyed by the garbage collector,
            #  and then we disconnect the signal that updates that layer.
            weak_predictLayer = weakref.ref(predictLayer)
            colortable_changed_callback = bind(self._setPredictionColorTable,
                                               weak_predictLayer)
            self._labelControlUi.labelListModel.dataChanged.connect(
                colortable_changed_callback)
            weak_predictLayer2 = weakref.ref(
                predictLayer,
                partial(self._disconnect_dataChange_callback,
                        colortable_changed_callback))
            # We have to make sure the weakref isn't destroyed because it is responsible for calling the callback.
            # Therefore, we retain it by adding it to a list.
            self._retained_weakrefs.append(weak_predictLayer2)

            # Ensure we're up-to-date (in case this is the first time the prediction layer is being added.
            for row in range(self._labelControlUi.labelListModel.rowCount()):
                self._setPredictionColorTableForRow(predictLayer, row)

            # put right after Labels, so that it is visible after hitting "live
            # predict".
            layers.insert(1, predictLayer)

        badObjectsSlot = self.op.BadObjectImages
        if badObjectsSlot.ready():
            ct_black = [0, QColor(Qt.black).rgba()]
            badSrc = LazyflowSource(badObjectsSlot)
            badLayer = ColortableLayer(badSrc, colorTable=ct_black)
            badLayer.name = "Ambiguous objects"
            badLayer.setToolTip(
                "Objects with infinite or invalid values in features")
            badLayer.visible = False
            layers.append(badLayer)

        if segmentedSlot.ready():
            ct = colortables.create_default_16bit()
            objectssrc = LazyflowSource(segmentedSlot)
            ct[0] = QColor(0, 0, 0, 0).rgba()  # make 0 transparent
            objLayer = ColortableLayer(objectssrc, ct)
            objLayer.name = "Objects"
            objLayer.opacity = 0.5
            objLayer.visible = False
            objLayer.setToolTip(
                "Segmented objects (labeled image/connected components)")
            layers.append(objLayer)

        if binarySlot.ready():
            ct_binary = [0, QColor(255, 255, 255, 255).rgba()]

            # white foreground on transparent background, even for labeled images
            binct = [QColor(255, 255, 255, 255).rgba()] * 65536
            binct[0] = 0
            binaryimagesrc = LazyflowSource(binarySlot)
            binLayer = ColortableLayer(binaryimagesrc, binct)
            binLayer.name = "Binary image"
            binLayer.visible = True
            binLayer.opacity = 1.0
            binLayer.setToolTip("Segmentation results as a binary mask")
            layers.append(binLayer)

        if rawSlot.ready():
            rawLayer = self.createStandardLayerFromSlot(rawSlot)
            rawLayer.name = "Raw data"

            def toggleTopToBottom():
                index = self.layerstack.layerIndex(rawLayer)
                self.layerstack.selectRow(index)
                if index == 0:
                    self.layerstack.moveSelectedToBottom()
                else:
                    self.layerstack.moveSelectedToTop()

            ActionInfo = ShortcutManager.ActionInfo
            rawLayer.shortcutRegistration = ("i",
                                             ActionInfo(
                                                 "Prediction Layers",
                                                 "Bring Input To Top/Bottom",
                                                 "Bring Input To Top/Bottom",
                                                 toggleTopToBottom,
                                                 self.viewerControlWidget(),
                                                 rawLayer))

            layers.append(rawLayer)

        # since we start with existing labels, it makes sense to start
        # with the first one selected. This would make more sense in
        # __init__(), but it does not take effect there.
        #self.selectLabel(0)

        return layers
Example #23
0
 def _create_random_colortable_layer_from_slot(cls, slot, num_colors=256):
     colortable = generateRandomColors(num_colors, clamp={'v': 1.0, 's' : 0.5}, zeroIsTransparent=True)
     layer = ColortableLayer(LazyflowSource(slot), colortable)
     layer.colortableIsRandom = True
     return layer
 def initGraph(self):
     shape = self.inputProvider.outputs["Output"].shape
     srcs    = []
     minMax = []
     normalize = []
     
     print "* Data has shape=%r" % (shape,)
     
     #create a layer for each channel of the input:
     slicer=OpMultiArraySlicer2(self.g)
     slicer.inputs["Input"].connect(self.inputProvider.outputs["Output"])
     slicer.inputs["AxisFlag"].setValue('c')
    
     nchannels = shape[-1]
     for ich in xrange(nchannels):
         data=slicer.outputs['Slices'][ich][:].allocate().wait()
         #find the minimum and maximum value for normalization
         mm = (numpy.min(data), numpy.max(data))
         print "  - channel %d: min=%r, max=%r" % (ich, mm[0], mm[1])
         minMax.append(mm)
         if self._normalize_data:
             normalize.append(mm)
         else:
             normalize.append((0,255))
         layersrc = LazyflowSource(slicer.outputs['Slices'][ich], priority = 100)
         layersrc.setObjectName("raw data channel=%d" % ich)
         srcs.append(layersrc)
         
     #FIXME: we shouldn't merge channels automatically, but for now it's prettier
     layer1 = None
     if nchannels == 1:
         layer1 = GrayscaleLayer(srcs[0], range=minMax[0], normalize=normalize[0])
         print "  - showing raw data as grayscale"
     elif nchannels==2:
         layer1 = RGBALayer(red  = srcs[0], normalizeR=normalize[0],
                            green = srcs[1], normalizeG=normalize[1], range=minMax[0:2]+[(0,255), (0,255)])
         print "  - showing channel 1 as red, channel 2 as green"
     elif nchannels==3:
         layer1 = RGBALayer(red   = srcs[0], normalizeR=normalize[0],
                            green = srcs[1], normalizeG=normalize[1],
                            blue  = srcs[2], normalizeB=normalize[2],
                            range = minMax[0:3])
         print "  - showing channel 1 as red, channel 2 as green, channel 3 as blue"
     else:
         print "only 1,2 or 3 channels supported so far"
         return
     print
     
     layer1.name = "Input data"
     layer1.ref_object = None
     self.layerstack.append(layer1)
     
     opImageList = Op5ToMulti(self.g)    
     opImageList.inputs["Input0"].connect(self.inputProvider.outputs["Output"])
     
     #init the features operator
     opPF = OpPixelFeaturesPresmoothed(self.g)
     opPF.inputs["Input"].connect(opImageList.outputs["Outputs"])
     opPF.inputs["Scales"].setValue(self.featScalesList)
     self.opPF=opPF
     
     #Caches the features
     opFeatureCache = OpBlockedArrayCache(self.g)
     opFeatureCache.inputs["innerBlockShape"].setValue((1,32,32,32,16))
     opFeatureCache.inputs["outerBlockShape"].setValue((1,128,128,128,64))
     opFeatureCache.inputs["Input"].connect(opPF.outputs["Output"])
     opFeatureCache.inputs["fixAtCurrent"].setValue(False)  
     self.opFeatureCache=opFeatureCache
     
     
     self.initLabels()
     self.dataReadyToView.emit()
    def setupLayers(self):
        layers = []
        opLane = self.topLevelOperatorView

        # This code depends on a specific order for the export slots.
        # If those change, update this function!
        selection_names = opLane.SelectionNames.value

        # see comment above
        for name, expected in zip(selection_names[0:5], [
                'Probabilities', 'Simple Segmentation', 'Uncertainty',
                'Features', 'Labels'
        ]):
            assert name.startswith(
                expected
            ), "The Selection Names don't match the expected selection names."

        selection = selection_names[opLane.InputSelection.value]

        if selection.startswith('Probabilities'):
            exportedLayers = self._initPredictionLayers(opLane.ImageOnDisk)
            for layer in exportedLayers:
                layer.visible = True
                layer.name = layer.name + "- Exported"
            layers += exportedLayers

            previewLayers = self._initPredictionLayers(opLane.ImageToExport)
            for layer in previewLayers:
                layer.visible = False
                layer.name = layer.name + "- Preview"
            layers += previewLayers
        elif selection.startswith(
                "Simple Segmentation") or selection.startswith("Labels"):
            exportedLayer = self._initColortablelayer(opLane.ImageOnDisk)
            if exportedLayer:
                exportedLayer.visible = True
                exportedLayer.name = selection + " - Exported"
                layers.append(exportedLayer)

            previewLayer = self._initColortablelayer(opLane.ImageToExport)
            if previewLayer:
                previewLayer.visible = False
                previewLayer.name = selection + " - Preview"
                layers.append(previewLayer)
        elif selection.startswith("Uncertainty"):
            if opLane.ImageToExport.ready():
                previewUncertaintySource = LazyflowSource(opLane.ImageToExport)
                previewLayer = AlphaModulatedLayer(
                    previewUncertaintySource,
                    tintColor=QColor(0, 255, 255),  # cyan
                    range=(0.0, 1.0),
                    normalize=(0.0, 1.0))
                previewLayer.opacity = 0.5
                previewLayer.visible = False
                previewLayer.name = "Uncertainty - Preview"
                layers.append(previewLayer)
            if opLane.ImageOnDisk.ready():
                exportedUncertaintySource = LazyflowSource(opLane.ImageOnDisk)
                exportedLayer = AlphaModulatedLayer(
                    exportedUncertaintySource,
                    tintColor=QColor(0, 255, 255),  # cyan
                    range=(0.0, 1.0),
                    normalize=(0.0, 1.0))
                exportedLayer.opacity = 0.5
                exportedLayer.visible = True
                exportedLayer.name = "Uncertainty - Exported"
                layers.append(exportedLayer)

        else:  # Features and all other layers.
            if selection.startswith("Features"):
                warnings.warn(
                    "Not sure how to display '{}' result.  Showing with default layer settings."
                    .format(selection))

            if opLane.ImageToExport.ready():
                previewLayer = self.createStandardLayerFromSlot(
                    opLane.ImageToExport)
                previewLayer.visible = False
                previewLayer.name = "{} - Preview".format(selection)
                previewLayer.set_normalize(0, None)
                layers.append(previewLayer)
            if opLane.ImageOnDisk.ready():
                exportedLayer = self.createStandardLayerFromSlot(
                    opLane.ImageOnDisk)
                exportedLayer.visible = True
                exportedLayer.name = "{} - Exported".format(selection)
                exportedLayer.set_normalize(0, None)
                layers.append(exportedLayer)

        # If available, also show the raw data layer
        rawSlot = opLane.FormattedRawData
        if rawSlot.ready():
            rawLayer = self.createStandardLayerFromSlot(rawSlot)
            rawLayer.name = "Raw Data"
            rawLayer.visible = True
            rawLayer.opacity = 1.0
            layers.append(rawLayer)

        return layers
Example #26
0
    def setupLayers(self):
        layers = []
        op = self.topLevelOperatorView
        binct = [QColor(Qt.black), QColor(Qt.white)]
        binct[0] = 0
        ct = create_default_16bit()
        ct[0] = 0
        # Show the cached output, since it goes through a blocked cache

        if op.CachedOutput.ready():
            outputSrc = LazyflowSource(op.CachedOutput)
            outputLayer = ColortableLayer(outputSrc, ct)
            outputLayer.name = "Final output"
            outputLayer.visible = False
            outputLayer.opacity = 1.0
            outputLayer.setToolTip("Results of thresholding and size filter")
            layers.append(outputLayer)

        if op.InputChannelColors.ready():
            input_channel_colors = map(lambda (r, g, b): QColor(r, g, b),
                                       op.InputChannelColors.value)
        else:
            input_channel_colors = map(QColor, self._defaultInputChannelColors)
        for channel, channelProvider in enumerate(self._channelProviders):
            slot_drange = channelProvider.Output.meta.drange
            if slot_drange is not None:
                drange = slot_drange
            else:
                drange = (0.0, 1.0)
            channelSrc = LazyflowSource(channelProvider.Output)
            inputChannelLayer = AlphaModulatedLayer(
                channelSrc,
                tintColor=input_channel_colors[channel],
                range=drange,
                normalize=drange)
            inputChannelLayer.opacity = 0.5
            inputChannelLayer.visible = True
            inputChannelLayer.name = "Input Channel " + str(channel)
            inputChannelLayer.setToolTip("Select input channel " + str(channel) + \
                                            " if this prediction image contains the objects of interest.")
            layers.append(inputChannelLayer)

        if self._showDebug:
            #FIXME: We have to do that, because lazyflow doesn't have a way to make an operator partially ready
            curIndex = op.CurOperator.value
            if curIndex == 1:
                if op.BigRegions.ready():
                    lowThresholdSrc = LazyflowSource(op.BigRegions)
                    lowThresholdLayer = ColortableLayer(lowThresholdSrc, binct)
                    lowThresholdLayer.name = "After low threshold"
                    lowThresholdLayer.visible = False
                    lowThresholdLayer.opacity = 1.0
                    lowThresholdLayer.setToolTip(
                        "Results of thresholding with the low pixel value threshold"
                    )
                    layers.append(lowThresholdLayer)

                if op.FilteredSmallLabels.ready():
                    filteredSmallLabelsSrc = LazyflowSource(
                        op.FilteredSmallLabels)
                    #filteredSmallLabelsLayer = self.createStandardLayerFromSlot( op.FilteredSmallLabels )
                    filteredSmallLabelsLayer = ColortableLayer(
                        filteredSmallLabelsSrc, binct)
                    filteredSmallLabelsLayer.name = "After high threshold and size filter"
                    filteredSmallLabelsLayer.visible = False
                    filteredSmallLabelsLayer.opacity = 1.0
                    filteredSmallLabelsLayer.setToolTip(
                        "Results of thresholding with the high pixel value threshold,\
                                                         followed by the size filter"
                    )
                    layers.append(filteredSmallLabelsLayer)

                if op.SmallRegions.ready():
                    highThresholdSrc = LazyflowSource(op.SmallRegions)
                    highThresholdLayer = ColortableLayer(
                        highThresholdSrc, binct)
                    highThresholdLayer.name = "After high threshold"
                    highThresholdLayer.visible = False
                    highThresholdLayer.opacity = 1.0
                    highThresholdLayer.setToolTip(
                        "Results of thresholding with the high pixel value threshold"
                    )
                    layers.append(highThresholdLayer)
            elif curIndex == 0:
                if op.BeforeSizeFilter.ready():
                    thSrc = LazyflowSource(op.BeforeSizeFilter)
                    thLayer = ColortableLayer(thSrc, ct)
                    thLayer.name = "Before size filter"
                    thLayer.visible = False
                    thLayer.opacity = 1.0
                    thLayer.setToolTip(
                        "Results of thresholding before the size filter is applied"
                    )
                    layers.append(thLayer)

            # Selected input channel, smoothed.
            if op.Smoothed.ready():
                smoothedLayer = self.createStandardLayerFromSlot(op.Smoothed)
                smoothedLayer.name = "Smoothed input"
                smoothedLayer.visible = True
                smoothedLayer.opacity = 1.0
                smoothedLayer.setToolTip(
                    "Selected channel data, smoothed with a Gaussian with user-defined sigma"
                )
                layers.append(smoothedLayer)

        # Show the raw input data
        rawSlot = self.topLevelOperatorView.RawInput
        if rawSlot.ready():
            rawLayer = self.createStandardLayerFromSlot(rawSlot)
            rawLayer.name = "Raw data"
            rawLayer.visible = True
            rawLayer.opacity = 1.0
            layers.append(rawLayer)

        return layers
Example #27
0
    def setupLayers(self):
        """
        Called by our base class when one of our data slots has changed.
        This function creates a layer for each slot we want displayed in the volume editor.
        """
        # Base class provides the label layer.
        layers = super(PixelClassificationGui, self).setupLayers()

        # Add the uncertainty estimate layer
        uncertaintySlot = self.topLevelOperatorView.UncertaintyEstimate
        if uncertaintySlot.ready():
            uncertaintySrc = LazyflowSource(uncertaintySlot)
            uncertaintyLayer = AlphaModulatedLayer(uncertaintySrc,
                                                   tintColor=QColor(Qt.cyan),
                                                   range=(0.0, 1.0),
                                                   normalize=(0.0, 1.0))
            uncertaintyLayer.name = "Uncertainty"
            uncertaintyLayer.visible = False
            uncertaintyLayer.opacity = 1.0
            uncertaintyLayer.shortcutRegistration = (
                "Prediction Layers", "Show/Hide Uncertainty",
                QShortcut(QKeySequence("u"), self.viewerControlWidget(),
                          uncertaintyLayer.toggleVisible), uncertaintyLayer)
            layers.append(uncertaintyLayer)

        labels = self.labelListData

        # Add each of the segmentations
        for channel, segmentationSlot in enumerate(
                self.topLevelOperatorView.SegmentationChannels):
            if segmentationSlot.ready() and channel < len(labels):
                ref_label = labels[channel]
                segsrc = LazyflowSource(segmentationSlot)
                segLayer = AlphaModulatedLayer(segsrc,
                                               tintColor=ref_label.pmapColor(),
                                               range=(0.0, 1.0),
                                               normalize=(0.0, 1.0))

                segLayer.opacity = 1
                segLayer.visible = False  #self.labelingDrawerUi.liveUpdateButton.isChecked()
                segLayer.visibleChanged.connect(
                    self.updateShowSegmentationCheckbox)

                def setLayerColor(c, segLayer=segLayer):
                    segLayer.tintColor = c
                    self._update_rendering()

                def setSegLayerName(n, segLayer=segLayer):
                    oldname = segLayer.name
                    newName = "Segmentation (%s)" % n
                    segLayer.name = newName
                    if not self.render:
                        return
                    if oldname in self._renderedLayers:
                        label = self._renderedLayers.pop(oldname)
                        self._renderedLayers[newName] = label

                setSegLayerName(ref_label.name)

                ref_label.pmapColorChanged.connect(setLayerColor)
                ref_label.nameChanged.connect(setSegLayerName)
                #check if layer is 3d before adding the "Toggle 3D" option
                #this check is done this way to match the VolumeRenderer, in
                #case different 3d-axistags should be rendered like t-x-y
                #_axiskeys = segmentationSlot.meta.getAxisKeys()
                if len(segmentationSlot.meta.shape) == 4:
                    #the Renderer will cut out the last shape-dimension, so
                    #we're checking for 4 dimensions
                    self._setup_contexts(segLayer)
                layers.append(segLayer)

        # Add each of the predictions
        for channel, predictionSlot in enumerate(
                self.topLevelOperatorView.PredictionProbabilityChannels):
            if predictionSlot.ready() and channel < len(labels):
                ref_label = labels[channel]
                predictsrc = LazyflowSource(predictionSlot)
                predictLayer = AlphaModulatedLayer(
                    predictsrc,
                    tintColor=ref_label.pmapColor(),
                    range=(0.0, 1.0),
                    normalize=(0.0, 1.0))
                predictLayer.opacity = 0.25
                predictLayer.visible = self.labelingDrawerUi.liveUpdateButton.isChecked(
                )
                predictLayer.visibleChanged.connect(
                    self.updateShowPredictionCheckbox)

                def setLayerColor(c, predictLayer=predictLayer):
                    predictLayer.tintColor = c

                def setPredLayerName(n, predictLayer=predictLayer):
                    newName = "Prediction for %s" % n
                    predictLayer.name = newName

                setPredLayerName(ref_label.name)
                ref_label.pmapColorChanged.connect(setLayerColor)
                ref_label.nameChanged.connect(setPredLayerName)
                layers.append(predictLayer)

        # Add the raw data last (on the bottom)
        inputDataSlot = self.topLevelOperatorView.InputImages
        if inputDataSlot.ready():
            inputLayer = self.createStandardLayerFromSlot(inputDataSlot)
            inputLayer.name = "Input Data"
            inputLayer.visible = True
            inputLayer.opacity = 1.0

            def toggleTopToBottom():
                index = self.layerstack.layerIndex(inputLayer)
                self.layerstack.selectRow(index)
                if index == 0:
                    self.layerstack.moveSelectedToBottom()
                else:
                    self.layerstack.moveSelectedToTop()

            inputLayer.shortcutRegistration = ("Prediction Layers",
                                               "Bring Input To Top/Bottom",
                                               QShortcut(
                                                   QKeySequence("i"),
                                                   self.viewerControlWidget(),
                                                   toggleTopToBottom),
                                               inputLayer)
            layers.append(inputLayer)

        self.handleLabelSelectionChange()
        return layers
Example #28
0
    def createStandardLayerFromSlot(self, slot, lastChannelIsAlpha=False):
        """
        Generate a volumina layer using the given slot.
        Choose between grayscale or RGB depending on the number of channels.
        """
        def getRange(meta):
            if 'drange' in meta:
                return meta.drange
            if numpy.issubdtype(meta.dtype, numpy.integer):
                # We assume that ints range up to their max possible value,
                return (0, numpy.iinfo(meta.dtype).max)
            else:
                # If we don't know the range of the data, create a layer that is auto-normalized.
                # See volumina.pixelpipeline.datasources for details.
                return 'autoPercentiles'

        # Examine channel dimension to determine Grayscale vs. RGB
        shape = slot.meta.shape
        normalize = getRange(slot.meta)
        try:
            channelAxisIndex = slot.meta.axistags.index('c')
            #assert channelAxisIndex < len(slot.meta.axistags), \
            #    "slot %s has shape = %r, axistags = %r, but no channel dimension" \
            #    % (slot.name, slot.meta.shape, slot.meta.axistags)
            numChannels = shape[channelAxisIndex]
        except:
            numChannels = 1

        if lastChannelIsAlpha:
            assert numChannels <= 4, "Can't display a standard layer with more than four channels (with alpha).  Your image has {} channels.".format(
                numChannels)
        else:
            assert numChannels <= 3, "Can't display a standard layer with more than three channels (with no alpha).  Your image has {} channels.".format(
                numChannels)

        if numChannels == 1:
            assert not lastChannelIsAlpha, "Can't have an alpha channel if there is no color channel"
            source = LazyflowSource(slot)
            normSource = NormalizingSource(source, bounds=normalize)
            return GrayscaleLayer(normSource)

        assert numChannels > 2 or (numChannels == 2 and not lastChannelIsAlpha)
        redProvider = OpSingleChannelSelector(graph=slot.graph)
        redProvider.Input.connect(slot)
        redProvider.Index.setValue(0)
        redSource = LazyflowSource(redProvider.Output)
        redNormSource = NormalizingSource(redSource, bounds=normalize)

        greenProvider = OpSingleChannelSelector(graph=slot.graph)
        greenProvider.Input.connect(slot)
        greenProvider.Index.setValue(1)
        greenSource = LazyflowSource(greenProvider.Output)
        greenNormSource = NormalizingSource(greenSource, bounds=normalize)

        blueNormSource = None
        if numChannels > 3 or (numChannels == 3 and not lastChannelIsAlpha):
            blueProvider = OpSingleChannelSelector(graph=slot.graph)
            blueProvider.Input.connect(slot)
            blueProvider.Index.setValue(2)
            blueSource = LazyflowSource(blueProvider.Output)
            blueNormSource = NormalizingSource(blueSource, bounds=normalize)

        alphaNormSource = None
        if lastChannelIsAlpha:
            alphaProvider = OpSingleChannelSelector(graph=slot.graph)
            alphaProvider.Input.connect(slot)
            alphaProvider.Index.setValue(numChannels - 1)
            alphaSource = LazyflowSource(alphaProvider.Output)
            alphaNormSource = NormalizingSource(alphaSource, bounds=normalize)

        layer = RGBALayer(red=redNormSource,
                          green=greenNormSource,
                          blue=blueNormSource,
                          alpha=alphaNormSource)
        return layer
Example #29
0
    def setupLayers(self, currentImageIndex):
        """
        Called by our base class when one of our data slots has changed.
        This function creates a layer for each slot we want displayed in the volume editor.
        """
        # Base class provides the label layer.
        layers = super(PixelClassificationGui,
                       self).setupLayers(currentImageIndex)

        labels = self.labelListData

        # Add the uncertainty estimate layer
        uncertaintySlot = self.pipeline.UncertaintyEstimate[currentImageIndex]
        if uncertaintySlot.ready():
            uncertaintySrc = LazyflowSource(uncertaintySlot)
            uncertaintyLayer = AlphaModulatedLayer(uncertaintySrc,
                                                   tintColor=QColor(Qt.cyan),
                                                   range=(0.0, 1.0),
                                                   normalize=(0.0, 1.0))
            uncertaintyLayer.name = "Uncertainty"
            uncertaintyLayer.visible = False
            uncertaintyLayer.opacity = 1.0
            uncertaintyLayer.shortcutRegistration = (
                "Prediction Layers", "Show/Hide Uncertainty",
                QShortcut(QKeySequence("u"), self.viewerControlWidget(),
                          uncertaintyLayer.toggleVisible), uncertaintyLayer)
            layers.append(uncertaintyLayer)

        # Add each of the predictions
        for channel, predictionSlot in enumerate(
                self.pipeline.PredictionProbabilityChannels[currentImageIndex]
        ):
            if predictionSlot.ready() and channel < len(labels):
                ref_label = labels[channel]
                predictsrc = LazyflowSource(predictionSlot)
                predictLayer = AlphaModulatedLayer(predictsrc,
                                                   tintColor=ref_label.color,
                                                   range=(0.0, 1.0),
                                                   normalize=(0.0, 1.0))
                predictLayer.opacity = 0.25
                predictLayer.visible = self.labelingDrawerUi.checkInteractive.isChecked(
                )
                predictLayer.visibleChanged.connect(
                    self.updateShowPredictionCheckbox)

                def setLayerColor(c):
                    predictLayer.tintColor = c

                def setLayerName(n):
                    newName = "Prediction for %s" % ref_label.name
                    predictLayer.name = newName

                setLayerName(ref_label.name)

                ref_label.colorChanged.connect(setLayerColor)
                ref_label.nameChanged.connect(setLayerName)
                layers.append(predictLayer)

        # Add each of the segementations
        for channel, segmentationSlot in enumerate(
                self.pipeline.SegmentationChannels[currentImageIndex]):
            if segmentationSlot.ready() and channel < len(labels):
                ref_label = labels[channel]
                segsrc = LazyflowSource(segmentationSlot)
                segLayer = AlphaModulatedLayer(segsrc,
                                               tintColor=ref_label.color,
                                               range=(0.0, 1.0),
                                               normalize=(0.0, 1.0))
                segLayer.opacity = 1
                segLayer.visible = self.labelingDrawerUi.checkInteractive.isChecked(
                )
                segLayer.visibleChanged.connect(
                    self.updateShowSegmentationCheckbox)

                def setLayerColor(c):
                    segLayer.tintColor = c

                def setLayerName(n):
                    newName = "Segmentation (%s)" % ref_label.name
                    segLayer.name = newName

                setLayerName(ref_label.name)

                ref_label.colorChanged.connect(setLayerColor)
                ref_label.nameChanged.connect(setLayerName)
                layers.append(segLayer)

        # Add the raw data last (on the bottom)
        inputDataSlot = self.pipeline.InputImages[currentImageIndex]
        if inputDataSlot.ready():
            inputLayer = self.createStandardLayerFromSlot(inputDataSlot)
            inputLayer.name = "Input Data"
            inputLayer.visible = True
            inputLayer.opacity = 1.0

            def toggleTopToBottom():
                index = self.layerstack.layerIndex(inputLayer)
                self.layerstack.selectRow(index)
                if index == 0:
                    self.layerstack.moveSelectedToBottom()
                else:
                    self.layerstack.moveSelectedToTop()

            inputLayer.shortcutRegistration = ("Prediction Layers",
                                               "Bring Input To Top/Bottom",
                                               QShortcut(
                                                   QKeySequence("i"),
                                                   self.viewerControlWidget(),
                                                   toggleTopToBottom),
                                               inputLayer)
            layers.append(inputLayer)

        return layers