Exemplo n.º 1
0
    def test_buffer(self):

        # Some data that we need
        data = np.zeros(100, np.uint16)
        im2 = np.zeros((50, 50), np.uint16)
        im3 = np.zeros((20, 20, 20), np.uint16)
        shaders = gloo.VertexShader("x"), gloo.FragmentShader("x")

        items = [
            # Buffers
            (gloo.buffer.Buffer(target=gl.GL_ARRAY_BUFFER), 'set_data', data),
            (gloo.buffer.VertexBuffer(np.uint16), 'set_data', data),
            (gloo.buffer.ElementBuffer(np.uint16), 'set_data', data),
            # Textures
            (gloo.Texture2D(), 'set_data', im2),
            (gloo.Texture3D(), 'set_data', im3),
            # FBO stuff
            (gloo.RenderBuffer(), 'set_shape', (1, 1)),
            (gloo.FrameBuffer(), 'attach_color', gloo.RenderBuffer((1, 1))),
            # Shader stuff
            (gloo.VertexShader(), 'set_code', "x"),
            (gloo.FragmentShader(), 'set_code', "x"),
            (gloo.Program(), 'attach', shaders),
        ]

        for ob, funcname, value in items:
            self._fix_ob(ob)
            #print('Testing GLObject compliance for %s' % ob.__class__.__name__)

            # Initially a clear state
            self.assertEqual(ob._need_update, False)

            # Set value, now we should have a "dirty" state
            x = ob
            for part in funcname.split('.'):
                x = getattr(x, part)
            x(value)
            self.assertEqual(ob._need_update, True)

            # Activate the object
            ob.activate()
            # Now we should be activated
            self.assertEqual(len(ob._actions), 3)
            self.assertEqual(ob._actions[0], 'create')
            self.assertEqual(ob._actions.count('update'), 1)
            self.assertEqual(ob._actions.count('activate'), 1)

            # Deactivate
            ob.deactivate()
            # Now we should be deactivated
            self.assertEqual(len(ob._actions), 4)
            self.assertEqual(ob._actions[-1], 'deactivate')

            # Activate some more
            for i in range(10):
                ob.activate()

            # Create and update should not have been called
            self.assertEqual(ob._actions.count('create'), 1)
            self.assertEqual(ob._actions.count('update'), 1)
Exemplo n.º 2
0
    def __init__(self):
        app.Canvas.__init__(self, keys='interactive')
        self.size = W * 5, H * 5

        self.program = gloo.Program(VERT_SHADER, FRAG_SHADER)
        self.texture = gloo.Texture3D(I,
                                      interpolation='nearest',
                                      wrapping='clamp_to_edge')
        self.program['u_texture'] = self.texture
        self.program['i'] = 0.0
        self.program.bind(gloo.VertexBuffer(data))

        self.view = np.eye(4, dtype=np.float32)
        self.model = np.eye(4, dtype=np.float32)
        self.projection = np.eye(4, dtype=np.float32)

        self.program['u_model'] = self.model
        self.program['u_view'] = self.view
        self.projection = ortho(0, W, 0, H, -1, 1)
        self.program['u_projection'] = self.projection

        self.i = 0

        gloo.set_clear_color('white')

        self._timer = app.Timer('auto', connect=self.on_timer, start=True)
Exemplo n.º 3
0
    def get_texture3d(self, outtexture=None):
        """Pack N-channel image data into R, RG, RGB, RGBA Texture3D using self.channels projection.

           outtexture:
             None:     allocate new Texture3D
             not None: use existing Texture3D

           sets data in outtexture and returns the texture.
        """
        I0 = self.data

        # choose size for texture data
        D, H, W = self.data.shape[0:3]
        C = len(self.channels)

        if outtexture is None:
            format, internalformat = self._get_texture3d_format()
            print('allocating texture3D', (D, H, W, C), internalformat)
            outtexture = gloo.Texture3D(shape=(D, H, W, C),
                                        format=format,
                                        internalformat=internalformat)
        elif self.last_channels == self.channels:
            print('reusing texture')
            return outtexture
        else:
            print('regenerating texture')

        print((D, H, W, C), '<-', I0.shape, list(self.channels), I0.dtype)

        # normalize for OpenGL [0,1.0] or [0,2**N-1] and zero black-level
        maxval = float(I0.max())
        minval = float(I0.min())
        if maxval > minval:
            scale = 1.0 / (maxval - minval)
        else:
            scale = 1.0
        if I0.dtype == np.uint8 or I0.dtype == np.int8:
            tmpout = np.zeros((D, H, W, C), dtype=np.uint8)
            scale *= float(2**8 - 1)
        else:
            assert I0.dtype == np.float16 or I0.dtype == np.float32 or I0.dtype == np.uint16 or I0.dtype == np.int16
            tmpout = np.zeros((D, H, W, C), dtype=np.uint16)
            scale *= (2.0**16 - 1)

        # pack selected channels into texture
        for i in range(C):
            tmpout[:, :, :,
                   i] = (I0[:, :, :, self.channels[i]].astype(np.float32) -
                         minval) * scale

        self.last_channels = self.channels
        outtexture.set_data(tmpout)
        return outtexture
Exemplo n.º 4
0
    def _reform_image(self, I, meta, view_reduction):
        splits = [(datetime.datetime.now(), None)]
        
        self.raw_image = I
        analyzer, view_image, centroids, centroid_measures = batch_analyze(
            I, self.synapse_diam_microns, self.vicinity_diam_microns, self.redblur_microns, view_reduction
        )
        splits.append((datetime.datetime.now(), 'volume process'))

        centroid_status = np.zeros((256**3,), dtype=np.uint8)

        # get labeled voxels
        assert np.isnan(centroid_measures).sum() == 0
        print("measures range", centroid_measures.min(axis=0), centroid_measures.max(axis=0))
        print("centroids:", centroids.min(axis=0), centroids.max(axis=0))
        print("view_image shape:", view_image.shape)
        print("view_image range", view_image.min(), view_image.max())

        # align 3D textures for opengl?
        assert view_image.shape[3] < 4
        result_shape = tuple(list(map(
            lambda s, m: s + s%m,
            view_image.shape[0:3],
            [1, 1, 4]
        )) + [view_image.shape[3] >= 2 and 3 or 1])
        print("results shape:", result_shape)

        segment_map = self.splat_centroids(view_reduction, result_shape[0:3], centroids, centroid_measures)
        
        if centroid_measures.shape[0] <= (2**8-1):
            nb = 1
        elif centroid_measures.shape[0] <= (2**16-1):
            nb = 2
        else:
            assert centroid_measures.shape[0] <= (2**24-1), "too many segment IDs to RGB-pack"
            nb = 3

        if nb == 1:
            fmt = 'red'
        else:
            fmt = 'rgb'[0:nb]

        print("voxel_class_texture %d segments, %d bytes, %s format" % (centroid_measures.shape[0], nb, fmt))
            
        # pack least significant byte as R, then G, etc.
        segment_map_uint8 = np.zeros(segment_map.shape + (nb,), dtype=np.uint8)
        for i in range(nb):
            segment_map_uint8[:,:,:,i] = (segment_map[:,:,:] // (2**(i*8))) % 2**8

        del segment_map
        self.voxel_class_texture = gloo.Texture3D(segment_map_uint8.shape, format=fmt)
        self.voxel_class_texture.set_data(segment_map_uint8)
        self.voxel_class_texture.interpolation = 'nearest'
        self.voxel_class_texture.wrapping = 'clamp_to_edge'
        del segment_map_uint8
        splits.append((datetime.datetime.now(), 'segment texture'))

        self.data_max = max(
            view_image[:,:,:,0].max(),
            centroid_measures[:,0:2].max()
        )
        self.data_min = min(
            view_image[:,:,:,0].min(),
            centroid_measures[:,0:2].min()
        )

        if view_image.shape[3] > 1:
            self.data_max = max(
                self.data_max,
                view_image[:,:,:,1].max(),
                centroid_measures[:,4].max()
            )
            self.data_min = min(
                self.data_min,
                view_image[:,:,:,1].min(),
                centroid_measures[:,4].min()
            )
        
        # pack segment measures into a 3D grid
        max_classid = centroid_measures.shape[0] + 1
        W = 256
        seg_meas = np.zeros((W, W, W, 3), dtype=np.float32)
        seg_meas_flat = seg_meas.reshape((W**3, 3))
        seg_meas_flat[1:max_classid,0:2] = centroid_measures[:,0:2]
        if centroid_measures.shape[1] > 4:
            seg_meas_flat[1:max_classid,2] = centroid_measures[:,4]

        seg_meas = (seg_meas - self.data_min) / (self.data_max - self.data_min)

        self.measures_texture = gloo.Texture3D(seg_meas.shape, format='rgb', internalformat='rgb16f')
        self.measures_texture.set_data(seg_meas)
        self.measures_texture.interpolation = 'nearest'
        self.measures_texture.wrapping = 'clamp_to_edge'
        self.status_texture = gloo.Texture3D((W,W,W,1), format='red', internalformat='red')
        self.status_texture.set_data(centroid_status.reshape((W,W,W,1)))
        self.status_texture.interpolation = 'nearest'
        self.status_texture.wrapping = 'clamp_to_edge'
        splits.append((datetime.datetime.now(), 'segment measures and status textures'))

        result = np.zeros(result_shape, dtype=np.float32)
        result[0,0,0,0] = self.data_min
        result[0,0,1,0] = self.data_max
        result_box = result[
            0:view_image.shape[0],
            0:view_image.shape[1],
            0:view_image.shape[2],
            :
        ]
        result_box[:,:,:,0] = view_image[:,:,:,0]
            
        splits.append((datetime.datetime.now(), 'scalar volume'))
            
        perf_vector = list(map(lambda t0, t1: ((t1[0]-t0[0]).total_seconds(), t1[1]), splits[0:-1], splits[1:]))
        for elapsed, desc in perf_vector:
            print("%8.2fs %s task time" % (elapsed, desc))
        
        print("measure counts:", centroid_measures.shape)
        print("packed data range: ", self.data_min, self.data_max)

        self.analyzer = analyzer
        self.syn_values = centroid_measures[:,0]
        self.vcn_values = centroid_measures[:,1]
        if centroid_measures.shape[1] > 4:
            self.red_values = centroid_measures[:,2]
        else:
            self.red_values = np.zeros((centroid_measures.shape[0],), dtype=np.float32)
        self.centroids = centroids
        self.centroid_measures = centroid_measures
        self.centroid_status = centroid_status
        #self.widths = widths

        return result
Exemplo n.º 5
0
    def get_textures(self, Z):
        """Returns ((image_texture, map_texture, measures_texture), map_ndarray, status3d_flat)"""
        I0 = self.data

        # choose size for texture data
        D, H, W = self.data.shape[0:3]
        C = len(self.channels)

        if self.textures is None:
            format, internalformat = self._get_texture_format(
                len(self.channels), 2)
            #print 'allocating textures...'
            self.textures = [
                gloo.Texture2D(shape=(H, W, C),
                               format=format,
                               internalformat=internalformat),
                gloo.Texture2D(shape=(H, W, 3),
                               format='rgb',
                               internalformat='rgb'),
                gloo.Texture3D(shape=(256, 256, 256, 3),
                               format='rgb',
                               internalformat='rgb16f'),
                gloo.Texture3D(shape=(256, 256, 256),
                               format='luminance',
                               internalformat='red'),
            ]
            self.map_ndarray = np.zeros((H, W, 4), dtype=np.uint8)
            self.measures3d = np.zeros((256, 256, 256, 3), dtype=np.float32)
            self.status3d = np.zeros((256, 256, 256), dtype=np.uint8)
            for texture in self.textures:
                texture.interpolation = 'nearest'
                texture.wrapping = 'clamp_to_edge'

            if self.statuses is not None:
                # if NPZ included initial status, load it here!
                status3d_flat = self.status3d.reshape((256**3, ))
                status3d_flat[1:self.statuses.shape[0] + 1] = self.statuses[:]

        elif self.last_channels == self.channels and self.last_Z == Z:
            #print 'reusing textures'
            return self.textures
        else:
            #print 'regenerating texture'
            pass

        # normalize image data for OpenGL [0,1.0] or [0,2**N-1] and zero black-level
        scale = 1.0 / self.value_norm
        if I0.dtype == np.uint8 or I0.dtype == np.int8:
            tmpout = np.zeros((H, W, C), dtype=np.uint8)
            scale *= float(2**8 - 1)
        else:
            assert I0.dtype == np.float16 or I0.dtype == np.float32 or I0.dtype == np.uint16 or I0.dtype == np.int16
            tmpout = np.zeros((H, W, C), dtype=np.uint16)
            scale *= (2.0**16 - 1)

        # pack selected channels into texture
        for i in range(C):
            tmpout[:, :,
                   i] = (I0[Z, :, :, self.channels[i]].astype(np.float32) -
                         self.minval) * scale

        self.last_channels = self.channels
        self.last_Z = Z
        self.textures[0].set_data(tmpout)

        # splat intersecting segment IDs into map texture
        tmpout = np.zeros((H, W, 4), dtype=np.uint8)
        self.map_ndarray[:, :, :] = 0

        indices = ((self.centroids[:, 0] >= Z - self.z_radius) *
                   (self.centroids[:, 0] <= Z + self.z_radius)).nonzero()[0]

        if indices.shape[0] > len(self.kernel_slices):
            # optimized for a bunch of points spread around a little
            for i in range(indices.shape[0]):
                idx = indices[i]
                y, x = self.centroids[idx, 1:3]
                idx += 1  # offset indices 0..N-1 as 1..N
                tmpout[y, x, 0] = idx % 2**8
                tmpout[y, x, 1] = (idx // 2**8) % 2**8
                tmpout[y, x, 2] = (idx // 2**16) % 2**8

            for dyslc, dxslc, syslc, sxslc in self.kernel_slices:
                dst = self.map_ndarray[dyslc, dxslc, :]
                dst_not_filled = ((dst[:, :, 0] == 0) * (dst[:, :, 1] == 0) *
                                  (dst[:, :, 2] == 0))[:, :, None]
                dst += tmpout[syslc, sxslc, :] * dst_not_filled
            # end loop (synspy#33 was indentation regression on previous line!)
        else:
            # optimized for fewer points spread around a lot
            for i in range(indices.shape[0]):
                idx = indices[i]
                y, x = self.centroids[idx, 1:3]
                idx += 1  # offset 0..N-1 as 1..N
                r = idx % 2**8
                g = (idx // 2**8) % 2**8
                b = (idx // 2**16) % 2**8
                if self.kernel_radius < y < (self.map_ndarray.shape[0] - self.kernel_radius) \
                   and self.kernel_radius < x < (self.map_ndarray.shape[1] - self.kernel_radius):
                    dslc = (
                        slice(y - self.kernel_radius,
                              y + self.kernel_radius + 1),
                        slice(x - self.kernel_radius,
                              x + self.kernel_radius + 1),
                    )
                    dst_not_filled = ((self.map_ndarray[dslc + (0, )] == 0) *
                                      (self.map_ndarray[dslc + (1, )] == 0) *
                                      (self.map_ndarray[dslc + (2, )] == 0))
                    self.map_ndarray[dslc + (
                        0,
                    )] = r * dst_not_filled * self.kernel_splat + self.map_ndarray[
                        dslc + (0, )]
                    self.map_ndarray[dslc + (
                        1,
                    )] = g * dst_not_filled * self.kernel_splat + self.map_ndarray[
                        dslc + (1, )]
                    self.map_ndarray[dslc + (
                        2,
                    )] = b * dst_not_filled * self.kernel_splat + self.map_ndarray[
                        dslc + (2, )]

        # pack measures into 3D grid
        meas3d_flat = self.measures3d.reshape((256**3, 3))
        meas3d_flat[1:self.measures.shape[0] + 1, 0:2] = self.measures[:, 0:2]
        if self.measures.shape[1] > 4:
            meas3d_flat[1:self.measures.shape[0] + 1, 2] = self.measures[:, 4]

        # renormalize to [0,1]
        self.measures3d[:, :] = self.measures3d[:, :] * (1.0 / self.value_norm)

        # pack statuses into 3D grid
        status3d_flat = self.status3d.reshape((256**3, ))

        self.textures[1].set_data(self.map_ndarray)
        self.textures[2].set_data(self.measures3d)
        self.textures[3].set_data(self.status3d)

        return self.textures, self.map_ndarray, status3d_flat