예제 #1
0
def genMeshColour(overlay):
    """Called by :meth:`MeshOpts.__init__`. Generates an initial colour for
    the given :class:`.Mesh` overlay.

    If the overlay file name looks like it was generated by the FSL FIRST
    segmentation tool, returns a colour from the ``freesurfercolorlut`` colour
    map. Otherwise returns a random colour.
    """
    filename = str(overlay.dataSource)
    subcorticalCmap = colourmaps.getLookupTable('freesurfercolorlut')

    if 'L_Thal' in filename: return subcorticalCmap.get(10).colour
    elif 'L_Caud' in filename: return subcorticalCmap.get(11).colour
    elif 'L_Puta' in filename: return subcorticalCmap.get(12).colour
    elif 'L_Pall' in filename: return subcorticalCmap.get(13).colour
    elif 'BrStem' in filename: return subcorticalCmap.get(16).colour
    elif 'L_Hipp' in filename: return subcorticalCmap.get(17).colour
    elif 'L_Amyg' in filename: return subcorticalCmap.get(18).colour
    elif 'L_Accu' in filename: return subcorticalCmap.get(26).colour
    elif 'R_Thal' in filename: return subcorticalCmap.get(49).colour
    elif 'R_Caud' in filename: return subcorticalCmap.get(50).colour
    elif 'R_Puta' in filename: return subcorticalCmap.get(51).colour
    elif 'R_Pall' in filename: return subcorticalCmap.get(52).colour
    elif 'R_Hipp' in filename: return subcorticalCmap.get(53).colour
    elif 'R_Amyg' in filename: return subcorticalCmap.get(54).colour
    elif 'R_Accu' in filename: return subcorticalCmap.get(58).colour

    return colourmaps.randomBrightColour()
예제 #2
0
def test_randomX():
    c1 = fslcm.randomColour()
    c2 = fslcm.randomBrightColour()
    c3 = fslcm.randomDarkColour()

    for c in [c1, c2, c3]:
        assert c.shape == (3,)
        assert np.all((c >= 0) & (c <= 1))
예제 #3
0
    def drawClipPlanes(self, xform=None, bbox=None):
        """A convenience method for use with overlays being displayed
        in terms of a :class:`.Volume3DOpts` instance.

        Draws the active clipping planes, as specified by the
        :class:`.Volume3DOpts` clipping properties.

        :arg xform: A transformation matrix to apply to the clip plane
                    vertices before drawing them.

        :arg bbox:  A bounding box by which the clip planes can be limited
                    (not currently honoured).
        """

        if not self.opts.showClipPlanes:
            return

        for i in range(self.opts.numClipPlanes):

            verts, idxs = self.clipPlaneVertices(i, bbox)

            if len(idxs) == 0:
                continue

            if xform is not None:
                verts = transform.transform(verts, xform)

            verts = np.array(verts.ravel('C'), dtype=np.float32, copy=False)

            # A consistent colour for
            # each clipping plane
            rgb = self.__clipPlaneColours.get(i, None)
            if rgb is None:
                rgb = fslcmaps.randomBrightColour()[:3]
                self.__clipPlaneColours[i] = rgb

            r, g, b = rgb

            with glroutines.enabled(gl.GL_VERTEX_ARRAY):

                gl.glColor4f(r, g, b, 0.3)
                gl.glVertexPointer(3, gl.GL_FLOAT, 0, verts)
                gl.glDrawElements(gl.GL_TRIANGLES,
                                  len(idxs),
                                  gl.GL_UNSIGNED_INT,
                                  idxs)
예제 #4
0
    def __onLabelAdd(self, ev):
        """Called when the user pushes the *add* button on the lookup table
        label list. Displays a :class:`LutLabelDialog`, prompting the user
        to select a name, value and colour, and then adds a new label to the
        current :class:`.LookupTable` instance.
        """

        lut = self.__selectedLut
        value = lut.max() + 1
        name = strings.labels['LutLabelDialog.newLabel']
        colour = fslcmaps.randomBrightColour()
        colour = [int(round(c * 255.0)) for c in colour]

        dlg = LutLabelDialog(self.GetTopLevelParent(), value, name, colour)
        if dlg.ShowModal() != wx.ID_OK:
            return

        lut = self.__selectedLut
        value = dlg.GetValue()
        name = dlg.GetName()
        colour = dlg.GetColour()[:3]
        colour = [c / 255.0 for c in colour]

        if lut.get(value) is not None:
            wx.MessageBox(
                strings.messages[self, 'labelExists'].format(lut.name, value),
                strings.titles[self,
                               'labelExists'], (wx.ICON_INFORMATION | wx.OK))
            return

        log.debug('New lut label for {}: {}, {}, {}'.format(
            lut.name, value, name, colour))

        with lut.skip(self.name, 'added'):
            label = lut.insert(value, name=name, colour=colour)
            widget = LabelWidget(self, lut, label)
            idx = lut.index(label)
            self.__labelList.Insert(str(label.value),
                                    idx,
                                    clientData=label.value,
                                    extraWidget=widget)
예제 #5
0
        def applyLabels(labelFile, overlay, allLabels, newOverlay):
            # labelFile:  Path to the loaded label file
            # overlay:    Overlay to apply them to
            # allLabels:  Loaded labels (list of (component, [label]) tuples)
            # newOverlay: True if the selected overlay has changed, False
            #             otherwise

            lut       = self.__lut
            volLabels = self.overlayList.getData(overlay, 'VolumeLabels')

            ncomps  = volLabels.numComponents()
            nlabels = len(allLabels)

            # Error: number of labels in the
            # file is greater than the number
            # of components in the overlay.
            if ncomps < nlabels:
                msg   = strings.messages[self, 'wrongNComps'].format(
                    labelFile, overlay.dataSource)
                title = strings.titles[  self, 'loadError']
                wx.MessageBox(msg, title, wx.ICON_ERROR | wx.OK)
                return

            # Number of labels in the file is
            # less than number of components
            # in the overlay - we pad the
            # labels with 'Unknown'
            elif ncomps > nlabels:
                for i in range(nlabels, ncomps):
                    allLabels.append(['Unknown'])

            # Disable notification while applying
            # labels so the component/label grids
            # don't confuse themselves.
            with volLabels.skip(self.__componentGrid.name), \
                 volLabels.skip(self.__labelGrid    .name):

                volLabels.clear()

                for comp, lbls in enumerate(allLabels):
                    for lbl in lbls:
                        volLabels.addLabel(comp, lbl)

                # Make sure a colour in the melodic
                # lookup table exists for all labels
                for label in volLabels.getAllLabels():

                    label    = volLabels.getDisplayLabel(label)
                    lutLabel = lut.getByName(label)

                    if lutLabel is None:
                        log.debug('New melodic classification '
                                  'label: {}'.format(label))
                        lut.new(label, colour=fslcm.randomBrightColour())

            # New overlay was loaded
            if newOverlay:

                # Make sure the new image is selected.
                with props.skip(self.displayCtx,
                                'selectedOverlay',
                                self.name):
                    self.displayCtx.selectOverlay(overlay)

                self.__componentGrid.setOverlay(overlay)
                self.__labelGrid    .setOverlay(overlay)

            # Labels were applied to
            # already selected overlay.
            else:
                self.__componentGrid.refreshTags()
                self.__labelGrid    .refreshTags()