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()
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))
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)
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)
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()