Example #1
0
def smooth_3d(vol, smooth_factor=3, correct=True):
    """Smooth a 3-D volume.

    Parameters
    ----------
    vol : array_like
        The volume of shape (N, M, P)
    smooth_factor : int | 3
        The smoothing factor.

    Returns
    -------
    vol_smooth : array_like
        The smooth volume with the same shape as vol.
    """
    tf = NullTransform()
    # No smoothing :
    if (not isinstance(smooth_factor, int)) or (smooth_factor < 3):
        return vol, tf
    # Smoothing array :
    sz = np.full((3, ), smooth_factor, dtype=int)
    smooth = np.ones([smooth_factor] * 3) / np.prod(sz)
    # Apply smoothing :
    sm = fftconvolve(vol, smooth, mode='same')
    if correct:
        # Get the shape of the vol and the one with 'full' convolution :
        vx, vy, vz = vol.shape
        vcx, vcy, vcz = np.array([vx, vy, vz]) + smooth_factor - 1
        # Define transform :
        sc = [vx / vcx, vy / vcy, vz / vcz]
        tr = .5 * np.array([smooth_factor] * 3)
        tf = STTransform(scale=sc, translate=tr)
    return sm, tf
Example #2
0
    def __init__(self):
        app.Canvas.__init__(self, title="Windbarb plot", keys="interactive",
                            size=(830, 430))

        self.windbarb_length = 25
        self.grid_spacing = 50

        self.grid_coords = None
        self.line_vertices = None
        self.last_mouse = (0, 0)

        self.generate_grid()

        direction_vectors = (self.grid_coords - self.last_mouse).astype(
            np.float32)
        direction_vectors[:] /= 10
        direction_vectors[:, 1] *= -1

        self.visual = WindbarbVisual(pos=self.grid_coords,
                                     wind=direction_vectors,
                                     trig=False,
                                     edge_color='black',
                                     face_color='black',
                                     size=self.windbarb_length)

        self.visual.events.update.connect(lambda evt: self.update())
        self.visual.transform = NullTransform()

        self.show()
Example #3
0
    def __init__(self):
        app.Canvas.__init__(self, keys='interactive', size=(800, 800))
        # Create several visuals demonstrating different features of Line
        self.lines = [
            # agg-method lines:
            # per-vertex color
            visuals.LineVisual(pos=pos, color=color, method='agg'),
            # solid
            visuals.LineVisual(pos=pos, color=(0, 0.5, 0.3, 1), method='agg'),
            # wide
            visuals.LineVisual(pos=pos, color=color, width=5, method='agg'),

            # GL-method lines:
            visuals.LineVisual(pos=pos, color=color, method='gl'),
            visuals.LineVisual(pos=pos, color=(0, 0.5, 0.3, 1), method='gl'),
            visuals.LineVisual(pos=pos, color=color, width=5, method='gl'),
            # GL-method: "connect" not available in AGG method yet

            # only connect alternate vert pairs
            visuals.LineVisual(pos=pos,
                               color=(0, 0.5, 0.3, 1),
                               connect='segments',
                               method='gl'),
            # connect specific pairs
            visuals.LineVisual(pos=pos,
                               color=(0, 0.5, 0.3, 1),
                               connect=connect,
                               method='gl'),
        ]
        counts = [0, 0]
        for i, line in enumerate(self.lines):
            # arrange lines in a grid
            tidx = (line.method == 'agg')
            x = 400 * tidx
            y = 140 * (counts[tidx] + 1)
            counts[tidx] += 1
            line.transform = STTransform(translate=[x, y])
            # redraw the canvas if any visuals request an update
            line.events.update.connect(lambda evt: self.update())

        self.texts = [
            visuals.TextVisual('GL',
                               bold=True,
                               font_size=24,
                               color='w',
                               pos=(200, 40)),
            visuals.TextVisual('Agg',
                               bold=True,
                               font_size=24,
                               color='w',
                               pos=(600, 40))
        ]
        for text in self.texts:
            text.transform = NullTransform()
        self.visuals = self.lines + self.texts
        self.show()
Example #4
0
    def __init__(self):
        app.Canvas.__init__(self,
                            title='Bezier lines example',
                            keys='interactive',
                            size=(400, 750))

        self.lines = [
            visuals.LineVisual(curves.curve4_bezier((10, 0), (50, -190),
                                                    (350, 190), (390, 0)),
                               color='w',
                               width=2,
                               method='agg'),
            visuals.LineVisual(curves.curve4_bezier((10, 0), (190, -190),
                                                    (210, 190), (390, 0)),
                               color='w',
                               width=2,
                               method='agg'),
            visuals.LineVisual(curves.curve3_bezier((10, 0), (30, 200),
                                                    (390, 0)),
                               color='w',
                               width=2,
                               method='agg')
        ]

        # Translate each line visual downwards
        for i, line in enumerate(self.lines):
            x = 0
            y = 200 * (i + 1)

            line.transform = STTransform(translate=[x, y])

        self.texts = [
            visuals.TextVisual('Third order curve',
                               bold=True,
                               color='w',
                               font_size=14,
                               pos=(200, 75)),
            visuals.TextVisual('Quadratic curve',
                               bold=True,
                               color='w',
                               font_size=14,
                               pos=(200, 525)),
        ]

        for text in self.texts:
            text.transform = NullTransform()

        self.visuals = self.lines + self.texts
        self.show()
Example #5
0
    def __init__(self,
                 atlas,
                 sprite_size=(16, 16),
                 point_cs='pixel',
                 method=None):
        if method is None:
            if 'GL_GEOMETRY_SHADER' in vispy.gloo.gl.__dict__:
                method = 'geometry'
            else:
                method = 'point_sprite'

        self.method = method
        self.point_cs = point_cs

        self.atlas = atlas
        self.atlas.atlas_changed.connect(self._atlas_changed)
        self.position = np.empty((0, 3), dtype='float32')
        self.sprite = np.empty((0, ), dtype='uint32')
        self.sprite_size = sprite_size
        self.fgcolor = np.empty((0, 4), dtype='float32')
        self.bgcolor = np.empty((0, 4), dtype='float32')

        self._atlas_tex = vispy.gloo.Texture2D(shape=(1, 1, 4),
                                               format='rgba',
                                               interpolation='nearest')
        self._atlas_map_tex = vispy.gloo.Texture1D(shape=(1, 4),
                                                   format='rgba',
                                                   internalformat='rgba32f',
                                                   interpolation='nearest')
        self._need_data_upload = False
        self._need_atlas_upload = True

        self._null_transform = NullTransform()

        if method == 'point_sprite':
            shaders = self.vertex_shader_2, self.fragment_shader_2
        elif method == 'geometry':
            shaders = self.vertex_shader_3, self.fragment_shader_3, self.geometry_shader_3
        else:
            raise ValueError('method must be "point_sprite" or "geometry"')
        vispy.visuals.Visual.__init__(self, *shaders)

        self._draw_mode = 'points'
        self.shared_program['position'] = vispy.gloo.VertexBuffer()
        self.shared_program['sprite'] = vispy.gloo.VertexBuffer()
        self.shared_program['fgcolor'] = vispy.gloo.VertexBuffer()
        self.shared_program['bgcolor'] = vispy.gloo.VertexBuffer()

        self.update_gl_state(depth_test=True)
Example #6
0
    def __init__(self):
        app.Canvas.__init__(self, size=(800, 600), keys="interactive")

        self.bars = []
        self.bars.append(get_left_orientation_bar())
        self.bars.append(get_right_orientation_bar())
        self.bars.append(get_top_orientation_bar())
        self.bars.append(get_bottom_orientation_bar())

        # construct a default transform that does identity scaling
        # and does not translate the coordinates
        transform = NullTransform()
        self.transform_sys = TransformSystem(self)
        self.transform_sys.visual_to_document = transform

        self.show()
Example #7
0
    def __init__(self):
        app.Canvas.__init__(self, size=(800, 600), keys="interactive")

        img_data = get_mandlebrot_escape_values(600, 400)
        self.image = ImageVisual(img_data, cmap=colormap)

        image_transform = STTransform(scale=(1.3, 1.3), translate=(100, 0))
        self.image_transform_sys = TransformSystem(self)
        self.image_transform_sys.visual_to_document = image_transform

        self.vertical_bar = get_vertical_bar()

        # construct a default transform that does identity scaling
        # and does not translate the coordinates
        colorbar_transform = NullTransform()
        self.colorbar_transform_sys = TransformSystem(self)
        self.colorbar_transform_sys.visual_to_document = colorbar_transform

        self.show()
Example #8
0
    def __init__(self):
        app.Canvas.__init__(self,
                            title="Quiver plot",
                            keys="interactive",
                            size=(830, 430))

        self.arrow_length = 20

        self.grid_coords = None
        self.line_vertices = None
        self.last_mouse = (0, 0)

        self.generate_grid()

        self.visual = visuals.ArrowVisual(color='white',
                                          connect='segments',
                                          arrow_size=8)

        self.visual.events.update.connect(lambda evt: self.update())
        self.visual.transform = NullTransform()

        self.show()
Example #9
0
 def __init__(self, bounds=(0, 0, 1, 1), transform=None):
     self.bounds = bounds  # (x, y, w, h)
     if transform is None:
         transform = NullTransform()
     self._transform = None
     self.transform = transform
Example #10
0
    def __init__(
        self,
        data=None,
        method='auto',
        grid=(1, 1),
        cmap='viridis',
        clim='auto',
        gamma=1.0,
        interpolation='nearest',
        **kwargs,
    ):
        self._data = None
        self._gamma = gamma

        # load 'float packed rgba8' interpolation kernel
        # to load float interpolation kernel use
        # `load_spatial_filters(packed=False)`
        kernel, self._interpolation_names = load_spatial_filters()

        self._kerneltex = Texture2D(kernel, interpolation='nearest')
        # The unpacking can be debugged by changing "spatial-filters.frag"
        # to have the "unpack" function just return the .r component. That
        # combined with using the below as the _kerneltex allows debugging
        # of the pipeline
        # self._kerneltex = Texture2D(kernel, interpolation='linear',
        #                             internalformat='r32f')

        # create interpolation shader functions for available
        # interpolations
        fun = [
            Function(_interpolation_template % n)
            for n in self._interpolation_names
        ]
        self._interpolation_names = [
            n.lower() for n in self._interpolation_names
        ]

        self._interpolation_fun = dict(zip(self._interpolation_names, fun))
        self._interpolation_names.sort()
        self._interpolation_names = tuple(self._interpolation_names)

        # overwrite "nearest" and "bilinear" spatial-filters
        # with  "hardware" interpolation _data_lookup_fn
        self._interpolation_fun['nearest'] = Function(_texture_lookup)
        self._interpolation_fun['bilinear'] = Function(_texture_lookup)

        if interpolation not in self._interpolation_names:
            raise ValueError("interpolation must be one of %s" %
                             ', '.join(self._interpolation_names))

        self._interpolation = interpolation

        # check texture interpolation
        if self._interpolation == 'bilinear':
            texture_interpolation = 'linear'
        else:
            texture_interpolation = 'nearest'

        self._method = method
        self._grid = grid
        self._texture_limits = None
        self._need_texture_upload = True
        self._need_vertex_update = True
        self._need_colortransform_update = True
        self._need_interpolation_update = True
        self._texture = Texture2D(np.zeros((1, 1, 4)),
                                  interpolation=texture_interpolation)
        self._subdiv_position = VertexBuffer()
        self._subdiv_texcoord = VertexBuffer()

        # impostor quad covers entire viewport
        vertices = np.array(
            [[-1, -1], [1, -1], [1, 1], [-1, -1], [1, 1], [-1, 1]],
            dtype=np.float32,
        )
        self._impostor_coords = VertexBuffer(vertices)
        self._null_tr = NullTransform()

        self._init_view(self)
        super(ImageVisual, self).__init__(vcode=VERT_SHADER, fcode=FRAG_SHADER)
        self.set_gl_state('translucent', cull_face=False)
        self._draw_mode = 'triangles'

        # define _data_lookup_fn as None, will be setup in
        # self._build_interpolation()
        self._data_lookup_fn = None

        self.clim = clim
        self.cmap = cmap
        if data is not None:
            self.set_data(data)
        self.freeze()
Example #11
0
    def __init__(self, data_arrays, origin_x, origin_y, cell_width, cell_height,
                 shape=None,
                 tile_shape=(DEFAULT_TILE_HEIGHT, DEFAULT_TILE_WIDTH),
                 texture_shape=(DEFAULT_TEXTURE_HEIGHT, DEFAULT_TEXTURE_WIDTH),
                 wrap_lon=False,
                 cmap='viridis', method='tiled', clim='auto', gamma=None,
                 interpolation='nearest', **kwargs):
        # projection properties to be filled in later
        self.cell_width = None
        self.cell_height = None
        self.origin_x = None
        self.origin_y = None
        self.shape = None

        if method != 'tiled':
            raise ValueError("Only 'tiled' method is currently supported")
        method = 'subdivide'
        grid = (1, 1)

        # visual nodes already have names, so be careful
        if not hasattr(self, "name"):
            self.name = kwargs.get("name", None)
        self._viewable_mesh_mask = None
        self._ref1 = None
        self._ref2 = None

        self.texture_shape = texture_shape
        self.tile_shape = tile_shape
        self.num_tex_tiles = self.texture_shape[0] * self.texture_shape[1]
        self._stride = 0  # Current stride is None when we are showing the overview
        self._latest_tile_box = None
        self.wrap_lon = wrap_lon
        self._tiles = {}

        # What tiles have we used and can we use (each texture uses the same 'state')
        self.texture_state = TextureTileState(self.num_tex_tiles)

        self.set_channels(data_arrays, shape=shape,
                          cell_width=cell_width, cell_height=cell_height,
                          origin_x=origin_x, origin_y=origin_y)
        self.ndim = len(self.shape) or [x for x in data_arrays if x is not None][0].ndim
        self.num_channels = len(data_arrays)

        # load 'float packed rgba8' interpolation kernel
        # to load float interpolation kernel use
        # `load_spatial_filters(packed=False)`
        kernel, self._interpolation_names = load_spatial_filters()

        self._kerneltex = Texture2D(kernel, interpolation='nearest')
        # The unpacking can be debugged by changing "spatial-filters.frag"
        # to have the "unpack" function just return the .r component. That
        # combined with using the below as the _kerneltex allows debugging
        # of the pipeline
        # self._kerneltex = Texture2D(kernel, interpolation='linear',
        #                             internalformat='r32f')

        # create interpolation shader functions for available
        # interpolations
        fun = [Function(_interpolation_template % n)
               for n in self._interpolation_names]
        self._interpolation_names = [n.lower()
                                     for n in self._interpolation_names]

        self._interpolation_fun = dict(zip(self._interpolation_names, fun))
        self._interpolation_names.sort()
        self._interpolation_names = tuple(self._interpolation_names)

        # overwrite "nearest" and "bilinear" spatial-filters
        # with  "hardware" interpolation _data_lookup_fn
        self._interpolation_fun['nearest'] = Function(_texture_lookup)
        self._interpolation_fun['bilinear'] = Function(_texture_lookup)

        if interpolation not in self._interpolation_names:
            raise ValueError("interpolation must be one of %s" %
                             ', '.join(self._interpolation_names))

        self._interpolation = interpolation

        # check texture interpolation
        if self._interpolation == 'bilinear':
            texture_interpolation = 'linear'
        else:
            texture_interpolation = 'nearest'

        self._method = method
        self._grid = grid
        self._need_texture_upload = True
        self._need_vertex_update = True
        self._need_colortransform_update = False
        self._need_interpolation_update = True
        self._textures = [TextureAtlas2D(self.texture_shape, tile_shape=self.tile_shape,
                                         interpolation=texture_interpolation,
                                         format="LUMINANCE", internalformat="R32F",
                                         ) for i in range(self.num_channels)
                          ]
        self._subdiv_position = VertexBuffer()
        self._subdiv_texcoord = VertexBuffer()

        # impostor quad covers entire viewport
        vertices = np.array([[-1, -1], [1, -1], [1, 1],
                             [-1, -1], [1, 1], [-1, 1]],
                            dtype=np.float32)
        self._impostor_coords = VertexBuffer(vertices)
        self._null_tr = NullTransform()

        self._init_view(self)
        if self.VERT_SHADER is None or self.FRAG_SHADER is None:
            raise RuntimeError("No shader specified for this subclass")
        super(ImageVisual, self).__init__(vcode=self.VERT_SHADER, fcode=self.FRAG_SHADER)
        self.set_gl_state('translucent', cull_face=False)
        self._draw_mode = 'triangles'

        # define _data_lookup_fn as None, will be setup in
        # self._build_interpolation()
        self._data_lookup_fns = [Function(_rgb_texture_lookup) for i in range(self.num_channels)]

        if isinstance(clim, str):
            if clim != 'auto':
                raise ValueError("C-limits can only be 'auto' or 2 floats for each provided channel")
            clim = [clim] * self.num_channels
        if not isinstance(cmap, (tuple, list)):
            cmap = [cmap] * self.num_channels

        assert (len(clim) == self.num_channels)
        assert (len(cmap) == self.num_channels)
        _clim = []
        _cmap = []
        for idx in range(self.num_channels):
            cl = clim[idx]
            if cl == 'auto':
                _clim.append((np.nanmin(data_arrays[idx]), np.nanmax(data_arrays[idx])))
            elif cl is None:
                # Color limits don't matter (either empty channel array or other)
                _clim.append((0., 1.))
            elif isinstance(cl, tuple) and len(cl) == 2:
                _clim.append(cl)
            else:
                raise ValueError("C-limits must be a 2-element tuple or the string 'auto' for each channel provided")

            cm = cmap[idx]
            _cmap.append(cm)
        self.clim = _clim
        self._texture_LUT = None
        self.gamma = gamma if gamma is not None else (1.,) * self.num_channels
        # only set colormap if it isn't None
        # (useful when a subclass's shader doesn't expect a colormap)
        if _cmap[0] is not None:
            self.cmap = _cmap[0]

        self.overview_info = None
        self.init_overview(data_arrays)

        self.freeze()
Example #12
0
    def __init__(self, data, origin_x, origin_y, cell_width, cell_height,
                 shape=None,
                 tile_shape=(DEFAULT_TILE_HEIGHT, DEFAULT_TILE_WIDTH),
                 texture_shape=(DEFAULT_TEXTURE_HEIGHT, DEFAULT_TEXTURE_WIDTH),
                 wrap_lon=False, projection=DEFAULT_PROJECTION,
                 cmap='viridis', method='tiled', clim='auto', gamma=1.,
                 interpolation='nearest', **kwargs):
        if method != 'tiled':
            raise ValueError("Only 'tiled' method is currently supported")
        method = 'subdivide'
        grid = (1, 1)

        # visual nodes already have names, so be careful
        if not hasattr(self, "name"):
            self.name = kwargs.get("name", None)
        self._viewable_mesh_mask = None
        self._ref1 = None
        self._ref2 = None

        self.origin_x = origin_x
        self.origin_y = origin_y
        self.cell_width = cell_width
        self.cell_height = cell_height  # Note: cell_height is usually negative
        self.texture_shape = texture_shape
        self.tile_shape = tile_shape
        self.num_tex_tiles = self.texture_shape[0] * self.texture_shape[1]
        self._stride = (0, 0)  # Current stride is None when we are showing the overview
        self._latest_tile_box = None
        self.wrap_lon = wrap_lon
        self._tiles = {}
        assert (shape or data is not None), "`data` or `shape` must be provided"
        self.shape = shape or data.shape
        self.ndim = len(self.shape) or data.ndim

        # Where does this image lie in this lonely world
        self.calc = TileCalculator(
            self.name,
            self.shape,
            Point(x=self.origin_x, y=self.origin_y),
            Resolution(dy=abs(self.cell_height), dx=abs(self.cell_width)),
            self.tile_shape,
            self.texture_shape,
            wrap_lon=self.wrap_lon,
            projection=projection,
        )
        # What tiles have we used and can we use
        self.texture_state = TextureTileState(self.num_tex_tiles)

        # load 'float packed rgba8' interpolation kernel
        # to load float interpolation kernel use
        # `load_spatial_filters(packed=False)`
        kernel, self._interpolation_names = load_spatial_filters()

        self._kerneltex = Texture2D(kernel, interpolation='nearest')
        # The unpacking can be debugged by changing "spatial-filters.frag"
        # to have the "unpack" function just return the .r component. That
        # combined with using the below as the _kerneltex allows debugging
        # of the pipeline
        # self._kerneltex = Texture2D(kernel, interpolation='linear',
        #                             internalformat='r32f')

        # create interpolation shader functions for available
        # interpolations
        fun = [Function(_interpolation_template % n)
               for n in self._interpolation_names]
        self._interpolation_names = [n.lower()
                                     for n in self._interpolation_names]

        self._interpolation_fun = dict(zip(self._interpolation_names, fun))
        self._interpolation_names.sort()
        self._interpolation_names = tuple(self._interpolation_names)

        # overwrite "nearest" and "bilinear" spatial-filters
        # with  "hardware" interpolation _data_lookup_fn
        self._interpolation_fun['nearest'] = Function(_texture_lookup)
        self._interpolation_fun['bilinear'] = Function(_texture_lookup)

        if interpolation not in self._interpolation_names:
            raise ValueError("interpolation must be one of %s" %
                             ', '.join(self._interpolation_names))

        self._interpolation = interpolation

        # check texture interpolation
        if self._interpolation == 'bilinear':
            texture_interpolation = 'linear'
        else:
            texture_interpolation = 'nearest'

        self._method = method
        self._grid = grid
        self._need_texture_upload = True
        self._need_vertex_update = True
        self._need_colortransform_update = True
        self._need_interpolation_update = True
        self._texture = TextureAtlas2D(self.texture_shape, tile_shape=self.tile_shape,
                                       interpolation=texture_interpolation,
                                       format="LUMINANCE", internalformat="R32F",
                                       )
        self._subdiv_position = VertexBuffer()
        self._subdiv_texcoord = VertexBuffer()

        # impostor quad covers entire viewport
        vertices = np.array([[-1, -1], [1, -1], [1, 1],
                             [-1, -1], [1, 1], [-1, 1]],
                            dtype=np.float32)
        self._impostor_coords = VertexBuffer(vertices)
        self._null_tr = NullTransform()

        self._init_view(self)
        super(ImageVisual, self).__init__(vcode=VERT_SHADER, fcode=FRAG_SHADER)
        self.set_gl_state('translucent', cull_face=False)
        self._draw_mode = 'triangles'

        # define _data_lookup_fn as None, will be setup in
        # self._build_interpolation()
        self._data_lookup_fn = None

        self.gamma = gamma
        self.clim = clim if clim != 'auto' else (np.nanmin(data), np.nanmax(data))
        self._texture_LUT = None
        self.cmap = cmap

        self.overview_info = None
        self.init_overview(data)
        # self.transform = PROJ4Transform(projection, inverse=True)

        self.freeze()
Example #13
0
 def return_node(self, node: ImageVisual) -> None:
     """Return a node that's no number being used."""
     if node is not None:
         node.parent = None  # Remove from the Scene Graph.
         node.transform = NullTransform()
         self.nodes.append(node)