def test_contour3d(self): """Test contour3d function""" from silx import sx # Lazy loading to avoid it to create QApplication coords = numpy.linspace(-10, 10, 64) z = coords.reshape(-1, 1, 1) y = coords.reshape(1, -1, 1) x = coords.reshape(1, 1, -1) data = numpy.sin(x * y * z) / (x * y * z) # Just data window = sx.contour3d(data) isosurfaces = window.getIsosurfaces() self.assertEqual(len(isosurfaces), 1) if not window.getPlot3DWidget().isValid(): self.skipTest("OpenGL context is not valid") # N contours + color colors = ['red', 'green', 'blue'] window = sx.contour3d(data, copy=False, contours=len(colors), color=colors) isosurfaces = window.getIsosurfaces() self.assertEqual(len(isosurfaces), len(colors)) for iso, color in zip(isosurfaces, colors): self.assertEqual(rgba(iso.getColor()), rgba(color)) # by isolevel, single color contours = 0.2, 0.5 window = sx.contour3d(data, copy=False, contours=contours, color='yellow') isosurfaces = window.getIsosurfaces() self.assertEqual(len(isosurfaces), len(contours)) for iso, level in zip(isosurfaces, contours): self.assertEqual(iso.getLevel(), level) self.assertEqual(rgba(iso.getColor()), rgba('yellow')) # Single isolevel, colormap window = sx.contour3d(data, copy=False, contours=0.5, colormap='gray', vmin=0.6, opacity=0.4) isosurfaces = window.getIsosurfaces() self.assertEqual(len(isosurfaces), 1) self.assertEqual(isosurfaces[0].getLevel(), 0.5) self.assertEqual(rgba(isosurfaces[0].getColor()), (0., 0., 0., 0.4))
def test_contour3d(self): """Test contour3d function""" coords = numpy.linspace(-10, 10, 64) z = coords.reshape(-1, 1, 1) y = coords.reshape(1, -1, 1) x = coords.reshape(1, 1, -1) data = numpy.sin(x * y * z) / (x * y * z) # Just data window = sx.contour3d(data) isosurfaces = window.getIsosurfaces() self.assertEqual(len(isosurfaces), 1) self._expose_and_close(window) if not window.getPlot3DWidget().isValid(): self.skipTest("OpenGL context is not valid") # N contours + color colors = ['red', 'green', 'blue'] window = sx.contour3d(data, copy=False, contours=len(colors), color=colors) isosurfaces = window.getIsosurfaces() self.assertEqual(len(isosurfaces), len(colors)) for iso, color in zip(isosurfaces, colors): self.assertEqual(rgba(iso.getColor()), rgba(color)) self._expose_and_close(window) # by isolevel, single color contours = 0.2, 0.5 window = sx.contour3d(data, copy=False, contours=contours, color='yellow') isosurfaces = window.getIsosurfaces() self.assertEqual(len(isosurfaces), len(contours)) for iso, level in zip(isosurfaces, contours): self.assertEqual(iso.getLevel(), level) self.assertEqual(rgba(iso.getColor()), rgba('yellow')) self._expose_and_close(window) # Single isolevel, colormap window = sx.contour3d(data, copy=False, contours=0.5, colormap='gray', vmin=0.6, opacity=0.4) isosurfaces = window.getIsosurfaces() self.assertEqual(len(isosurfaces), 1) self.assertEqual(isosurfaces[0].getLevel(), 0.5) self.assertEqual(rgba(isosurfaces[0].getColor()), (0., 0., 0., 0.4)) self._expose_and_close(window)
def test_contour3d(sx, qapp_utils): """Test contour3d function""" coords = numpy.linspace(-10, 10, 64) z = coords.reshape(-1, 1, 1) y = coords.reshape(1, -1, 1) x = coords.reshape(1, 1, -1) data = numpy.sin(x * y * z) / (x * y * z) # Just data window = sx.contour3d(data) isosurfaces = window.getIsosurfaces() assert len(isosurfaces) == 1 if not window.getPlot3DWidget().isValid(): del window, isosurfaces # Release widget reference pytest.skip("OpenGL context is not valid") # N contours + color colors = ['red', 'green', 'blue'] window = sx.contour3d(data, copy=False, contours=len(colors), color=colors) isosurfaces = window.getIsosurfaces() assert len(isosurfaces) == len(colors) for iso, color in zip(isosurfaces, colors): assert rgba(iso.getColor()) == rgba(color) # by isolevel, single color contours = 0.2, 0.5 window = sx.contour3d(data, copy=False, contours=contours, color='yellow') isosurfaces = window.getIsosurfaces() assert len(isosurfaces) == len(contours) for iso, level in zip(isosurfaces, contours): assert iso.getLevel() == level assert rgba(iso.getColor()) == rgba('yellow') # Single isolevel, colormap window = sx.contour3d(data, copy=False, contours=0.5, colormap='gray', vmin=0.6, opacity=0.4) isosurfaces = window.getIsosurfaces() assert len(isosurfaces) == 1 assert isosurfaces[0].getLevel() == 0.5 assert rgba(isosurfaces[0].getColor()) == (0., 0., 0., 0.4)
def maskArrayToRgba(mask, falseColor, trueColor): """ Returns an RGBA uint8 numpy array using colors to map True (usually masked pixels) and Flase (valid pixel) from the mask array. """ trueColor = numpy.array(colors.rgba(trueColor)) trueColor = (trueColor * 256.0).clip(0, 255).astype(numpy.uint8) falseColor = numpy.array(colors.rgba(falseColor)) falseColor = (falseColor * 256.0).clip(0, 255).astype(numpy.uint8) shape = mask.shape[0], mask.shape[1], 4 image = numpy.empty(shape, dtype=numpy.uint8) image[mask] = trueColor image[~mask] = falseColor return image
def testRGBA(self): """"Test rgba function with accepted values""" for name, test in self.TEST_COLORS.items(): color, expected = test with self.subTest(msg=name): result = colors.rgba(color) self.assertEqual(result, expected)
def setRoiProfile(self, roi): """Set the profile ROI which it the source of the following data to display. :param ProfileRoiMixIn roi: The profile ROI data source """ if roi is None: return self.__color = colors.rgba(roi.getColor())
def setBackgroundColor(self, color): """Set the background color of the OpenGL view. :param color: RGB color of the isosurface: name, #RRGGBB or RGB values :type color: QColor, str or array-like of 3 or 4 float in [0., 1.] or uint8 """ color = rgba(color) if color != self.viewport.background: self.viewport.background = color self.sigStyleChanged.emit('backgroundColor')
def __init__(self, parentRoi): items.Shape.__init__(self, "polygon") color = colors.rgba(parentRoi.getColor()) self.setColor(color) self.setFill(True) self.setOverlay(True) self.setPoints([[0, 0], [0, 0]]) # Else it segfault self.__parentRoi = weakref.ref(parentRoi) parentRoi.sigItemChanged.connect(self._updateAreaProperty) parentRoi.sigRegionChanged.connect(self._updateArea) parentRoi.sigProfilePropertyChanged.connect(self._updateArea) parentRoi.sigPlotItemChanged.connect(self._updateArea)
def setColor(self, color): """Set the color to use for ROI and profile. :param color: Either a color name, a QColor, a list of uint8 or float in [0, 1]. """ self._color = colors.rgba(color) roiManager = self._getRoiManager() if roiManager is not None: roiManager.setColor(self._color) for roi in roiManager.getRois(): roi.setColor(self._color) self.updateProfile()
def setMaskColors(self, rgb, level=None): """Set the masks color :param rgb: The rgb color :param level: The index of the mask for which we want to change the color. If none set this color for all the masks """ rgb = rgba(rgb)[0:3] if level is None: self._overlayColors[:] = rgb self._defaultColors[:] = False else: self._overlayColors[level] = rgb self._defaultColors[level] = False self._updateColors()
def __init__(self, parent=None, plot=None, mask=None): """ :param parent: Parent QWidget :param plot: Plot widget on which to operate :param mask: Instance of subclass of :class:`BaseMask` (e.g. :class:`ImageMask`) """ super(BaseMaskToolsWidget, self).__init__(parent) # register if the user as force a color for the corresponding mask level self._defaultColors = numpy.ones((self._maxLevelNumber + 1), dtype=numpy.bool) # overlays colors set by the user self._overlayColors = numpy.zeros((self._maxLevelNumber + 1, 3), dtype=numpy.float32) # as parent have to be the first argument of the widget to fit # QtDesigner need but here plot can't be None by default. assert plot is not None self._plotRef = weakref.ref(plot) self._maskName = '__MASK_TOOLS_%d' % id(self) # Legend of the mask self._colormap = Colormap(name="", normalization='linear', vmin=0, vmax=self._maxLevelNumber, colors=None) self._defaultOverlayColor = rgba('gray') # Color of the mask self._setMaskColors(1, 0.5) if not isinstance(mask, BaseMask): raise TypeError("mask is not an instance of BaseMask") self._mask = mask self._mask.sigChanged.connect(self._updatePlotMask) self._mask.sigChanged.connect(self._emitSigMaskChanged) self._drawingMode = None # Store current drawing mode self._lastPencilPos = None self._multipleMasks = 'exclusive' self._maskFileDir = qt.QDir.home().absolutePath() self.plot.sigInteractiveModeChanged.connect( self._interactiveModeChanged) self._initWidgets()
def testRGBA(self): """"Test rgba function with accepted values""" tests = { # name: (colors, expected values) 'blue': ('blue', (0., 0., 1., 1.)), '#010203': ('#010203', (1. / 255., 2. / 255., 3. / 255., 1.)), '#01020304': ('#01020304', (1. / 255., 2. / 255., 3. / 255., 4. / 255.)), '3 x uint8': (numpy.array((1, 255, 0), dtype=numpy.uint8), (1 / 255., 1., 0., 1.)), '4 x uint8': (numpy.array((1, 255, 0, 1), dtype=numpy.uint8), (1 / 255., 1., 0., 1 / 255.)), '3 x float overflow': ((3., 0.5, 1.), (1., 0.5, 1., 1.)), } for name, test in tests.items(): color, expected = test with self.subTest(msg=name): result = colors.rgba(color) self.assertEqual(result, expected)
def __updateMaskColor(self, color): maskTool = self.getMaskTool() # TODO: Not anymore needed for silx >= 0.10 color = colors.rgba(color)[0:3] maskTool.setMaskColors(color)
def _drawContours(self, values, color='gray', plot_timeout=100, plot_method='curve'): """Draw iso contours for given values Parameters ---------- values : list or array intensities at which to find contours color : string (optional) color of contours (among common color names) ['gray'] plot_timeout : int (optional) time in seconds befor the plot is interrupted plot_method : str (optional) method to use for the contour plot 'curve' -> self.addCurve, polygons as from find_contours 'curve_max' -> self.addCurve, one polygon (max length) 'curve_merge' -> self.addCurve, one polygon (concatenate) 'scatter' -> self.addScatter (only points) """ if self._ms is None: return ipolygon = 0 totTime = 0 for ivalue, value in enumerate(values): startTime = time.time() polygons = self._ms.find_contours(value) polTime = time.time() self._logger.debug(f"Found {len(polygons)} polygon at level {value}") totTime += polTime - startTime # prepare polygons list for plot_method if len(polygons) == 0: continue if len(polygons) > 1: if (plot_method == 'curve_max'): from sloth.utils.arrays import imax lengths = [len(x) for x in polygons] polygons = [polygons[imax(lengths)]] elif (plot_method == 'curve_merge') or (plot_method == 'scatter'): polygons = [np.concatenate(polygons, axis=0)] else: pass # define default contour style contourStyle = {"linestyle": "-", "linewidth": 0.5, "color": color} for polygon in polygons: legend = "polygon-%d" % ipolygon xpoly = polygon[:, 1] ypoly = polygon[:, 0] xscale = np.ones_like(xpoly) * self._scale[0] yscale = np.ones_like(ypoly) * self._scale[1] xorigin = np.ones_like(xpoly) * self._origin[0] yorigin = np.ones_like(ypoly) * self._origin[1] x = xpoly * xscale + xorigin y = ypoly * yscale + yorigin # plot timeout if totTime >= plot_timeout: self._logger.warning("Plot contours time out reached!") break # plot methods if plot_method == 'scatter': from silx.gui.colors import (Colormap, rgba) cm = Colormap() cm.setColormapLUT([rgba(color)]) arrval = np.ones_like(x)*value self.addScatter(x, y, arrval, symbol='.', colormap=cm) else: self.addCurve(x=x, y=y, legend=legend, resetzoom=False, **contourStyle) pltTime = time.time() totTime += pltTime - polTime ipolygon += 1
def background(self, color): if color is not None: color = rgba(color) if self._background != color: self._background = color self._changed()
def __createDetectorMesh(self): if self.__geometry is not None: if self.__detector is not None: self.__geometry.detector = self.__detector pixels = self.__geometry.calc_pos_zyx(corners=True) pixels = numpy.array(pixels) pixels = numpy.moveaxis(pixels, 0, -1) else: pixels = self.__detector.get_pixel_corners() height, width, _, _, = pixels.shape nb_vertices = width * height * 6 # Allocate contiguous memory positions_array = numpy.empty((nb_vertices, 3), dtype=numpy.float32) colors_array = numpy.empty((nb_vertices, 4), dtype=numpy.float32) # Merge all pixels together pixels = pixels[...] pixels = numpy.reshape(pixels, (-1, 4, 3)) image = self.__image mask = self.__mask colormap = self.__colormap if colormap is None: colormap = colors.Colormap("inferno") # Normalize the colormap as a RGBA float lookup table lut = colormap.getNColors(256) lut = lut / 255.0 cursor_color = colors.cursorColorForColormap(colormap.getName()) cursor_color = numpy.array(colors.rgba(cursor_color)) # Normalize the image as lookup table to colormap lookup table if image is not None: image = image.view() image.shape = -1 image = numpy.log(image) info = silx.math.combo.min_max(image, min_positive=True, finite=True) image = (image - info.min_positive) / float(info.maximum - info.min_positive) image = (image * 255.0).astype(int) image = image.clip(0, 255) if mask is not None: mask = mask.view() mask.shape = -1 masked_color = numpy.array([1.0, 0.0, 1.0, 1.0]) default_color = numpy.array([0.8, 0.8, 0.8, 1.0]) triangle_index = 0 color_index = 0 self.emitProgressValue(10, force=True) for npixel, pixel in enumerate(pixels): percent = 10 + int(90 * (npixel / len(pixels))) self.emitProgressValue(percent) if self.isInterruptionRequested(): return False masked = False if mask is not None: masked = mask[npixel] != 0 if masked: color = masked_color elif image is not None: color_id = image[color_index] color = lut[color_id] else: color = default_color positions_array[triangle_index + 0] = pixel[0] positions_array[triangle_index + 1] = pixel[1] positions_array[triangle_index + 2] = pixel[2] colors_array[triangle_index + 0] = color colors_array[triangle_index + 1] = color colors_array[triangle_index + 2] = color triangle_index += 3 positions_array[triangle_index + 0] = pixel[2] positions_array[triangle_index + 1] = pixel[3] positions_array[triangle_index + 2] = pixel[0] colors_array[triangle_index + 0] = color colors_array[triangle_index + 1] = color colors_array[triangle_index + 2] = color triangle_index += 3 color_index += 1 item = mesh.Mesh() item.moveToThread(qt.QApplication.instance().thread()) item.setData(position=positions_array, color=colors_array, copy=False) self.__detectorItem = item return True