Ejemplo n.º 1
0
def main():
    """
    This demo converts a selected TIFF image to an APR, writes the result to file and then reads the file.
    """

    io_int = pyapr.filegui.InteractiveIO()

    # Read in an image
    fpath = io_int.get_tiff_file_name()
    img = skio.imread(fpath).astype(np.uint16)

    # Instantiate objects
    apr = pyapr.APR()
    parts = pyapr.ShortParticles()
    par = pyapr.APRParameters()
    converter = pyapr.converter.ShortConverter()

    # Set some parameters
    par.auto_parameters = False
    par.rel_error = 0.1
    par.Ip_th = 10
    par.grad_th = 1
    par.gradient_smoothing = 2
    par.sigma_th = 20
    par.sigma_th_max = 10
    converter.set_parameters(par)
    converter.set_verbose(False)

    # Compute APR and sample particle values
    converter.get_apr(apr, img)
    parts.sample_image(apr, img)

    # Compute and display the computational ratio
    numParts = apr.total_number_particles()
    numPix = img.size
    cr = numPix / numParts
    print(
        'Input image size: {} pixels, APR size: {} particles --> Computational Ratio: {}'
        .format(numPix, numParts, cr))

    # Save the APR to file
    fpath_apr = io_int.save_apr_file_name()  # get save path from gui
    pyapr.io.write(fpath_apr, apr, parts)  # write apr and particles to file

    # Read the newly written file
    apr2 = pyapr.APR()
    parts2 = pyapr.ShortParticles()
    pyapr.io.read(fpath_apr, apr2, parts2)

    # check that particles are equal at a single, random index
    ri = np.random.randint(0, numParts - 1)
    assert parts[ri] == parts2[ri]

    # check some APR properties
    assert apr.total_number_particles() == apr2.total_number_particles()
    assert apr.level_max() == apr2.level_max()
    assert apr.level_min() == apr2.level_min()
Ejemplo n.º 2
0
    def setUp(self):

        self.numel = 113

        self.float1 = pyapr.FloatParticles(self.numel)
        self.float2 = pyapr.FloatParticles(self.numel)
        self.short1 = pyapr.ShortParticles(self.numel)
        self.short2 = pyapr.ShortParticles(self.numel)

        self.float1.fill(1)
        self.float2.fill(1 / 3)
        self.short1.fill(2)
        self.short2.fill(3)

        self.eps = 1e-6
Ejemplo n.º 3
0
    def test_io(self):
        print('Testing APR file IO')
        self.apr_parameters.output_steps = False
        # writes files to this path, later removes the file # TODO: find a better way to do this
        fpath = os.path.join(self.data_dir, 'temporary_apr_file.apr')

        for ndim, impath in zip(
            [1, 2, 3], [self.impath_1D, self.impath_2D, self.impath_3D]):
            print('{}D ... '.format(ndim), end="")
            img = skio.imread(impath)
            apr, parts = pyapr.converter.get_apr(img,
                                                 verbose=False,
                                                 params=self.apr_parameters)

            pyapr.io.write(fpath, apr, parts)

            apr2 = pyapr.APR()
            parts2 = pyapr.ShortParticles()

            pyapr.io.read(fpath, apr2, parts2)

            for i in range(3):
                self.assertEqual(apr.org_dims(i), apr2.org_dims(i))
            self.assertEqual(apr.total_number_particles(),
                             apr2.total_number_particles())
            self.assertEqual(apr.total_number_particles(), len(parts2))

            self.assertTrue(
                np.alltrue(
                    np.array(parts, copy=False) == np.array(parts2,
                                                            copy=False)))
            print('OK!')

        os.remove(fpath)  # remove temporary file
Ejemplo n.º 4
0
    def test_io(self):

        # writes files to this path, later removes the file # TODO: find a better way to do this
        fpath = os.path.join(self.this_dir, 'temporary_apr_file.apr')

        for impath in (self.impath_1D, self.impath_2D, self.impath_3D):
            img = skio.imread(impath)
            apr, parts = pyapr.converter.get_apr(img,
                                                 verbose=False,
                                                 params=self.apr_parameters)

            pyapr.io.write(fpath, apr, parts)

            apr2 = pyapr.APR()
            parts2 = pyapr.ShortParticles()

            pyapr.io.read(fpath, apr2, parts2)

            self.assertEqual(apr.org_dims(), apr2.org_dims())
            self.assertEqual(apr.total_number_particles(),
                             apr2.total_number_particles())
            self.assertEqual(apr.total_number_particles(), len(parts2))

            self.assertTrue(
                np.alltrue(
                    np.array(parts, copy=False) == np.array(parts2,
                                                            copy=False)))

        os.remove(fpath)  # remove temporary file
Ejemplo n.º 5
0
def main():
    """
    This demo showcases some of the available numerics functionality on a selected APR
    """

    io_int = pyapr.filegui.InteractiveIO()
    fpath_apr = io_int.get_apr_file_name()      # get APR file path from gui

    # Instantiate APR and particle objects
    apr = pyapr.APR()
    parts = pyapr.ShortParticles()              # input particles can be float32 or uint16
    # parts = pyapr.FloatParticles()

    # Read from APR file
    pyapr.io.read(fpath_apr, apr, parts)

    output = pyapr.FloatParticles()

    # Compute gradient along a dimension (Sobel filter). dimension can be 0, 1 or 2
    pyapr.numerics.gradient(apr, parts, output, dimension=0, delta=1.0, sobel=True)
    pyapr.viewer.parts_viewer(apr, output)   # Display the result

    # Compute gradient magnitude (central finite differences)
    pyapr.numerics.gradient_magnitude(apr, parts, output, deltas=(1.0, 1.0, 1.0), sobel=False)
    pyapr.viewer.parts_viewer(apr, output)  # Display the result

    # Compute local standard deviation around each particle
    pyapr.numerics.local_std(apr, parts, output, size=(5, 5, 5))
    pyapr.viewer.parts_viewer(apr, output)  # Display the result
Ejemplo n.º 6
0
def main():
    """
    Read a selected APR from file and apply Richardson-Lucy deconvolution
    """

    # Get input APR file path from gui
    io_int = pyapr.filegui.InteractiveIO()
    fpath_apr = io_int.get_apr_file_name()

    # Instantiate APR and particles objects
    apr = pyapr.APR()
    parts = pyapr.ShortParticles()
    # parts = pyapr.FloatParticles()

    # Read from APR file
    pyapr.io.read(fpath_apr, apr, parts)

    # Copy particles to float
    fparts = pyapr.FloatParticles()
    fparts.copy(parts)

    # Add a small offset to the particle values to avoid division by 0
    offset = 1e-5 * fparts.max()
    fparts += offset

    # Display the input image
    pyapr.viewer.parts_viewer(apr, fparts)

    # Specify the PSF and number of iterations
    psf = pyapr.numerics.filter.get_gaussian_stencil(size=5,
                                                     sigma=1,
                                                     ndims=3,
                                                     normalize=True)
    niter = 20

    # Perform richardson-lucy deconvolution
    output = pyapr.FloatParticles()
    pyapr.numerics.richardson_lucy(apr,
                                   fparts,
                                   output,
                                   psf,
                                   niter,
                                   use_stencil_downsample=True,
                                   normalize_stencil=True,
                                   resume=False)

    # Alternative using total variation regularization:
    # reg_factor = 1e-2
    # pyapr.numerics.richardson_lucy_tv(apr, fparts, output, psf, niter, reg_factor, use_stencil_downsample=True,
    #                                   normalize_stencil=True, resume=False)

    # Alternatively, if PyLibAPR is built with CUDA enabled and psf is of size (3, 3, 3) or (5, 5, 5)
    # pyapr.numerics.richardson_lucy_cuda(apr, fparts, output, psf, niter, use_stencil_downsample=True,
    #                                     normalize_stencil=True, resume=False)

    # Display the result
    pyapr.viewer.parts_viewer(apr, output)
Ejemplo n.º 7
0
def initialize_particles_type(typestr):
    if typestr == 'uint16':
        return pyapr.ShortParticles()
    if typestr == 'float':
        return pyapr.FloatParticles()
    if typestr == 'uint8':
        return pyapr.ByteParticles()
    if typestr == 'uint64':
        return pyapr.LongParticles()

    print('Deducted datatype {} is currently not supported - returning None'.
          format(typestr))
    return None
Ejemplo n.º 8
0
def main():
    """
    This demo illustrates three different pixel image reconstruction methods:

        piecewise constant      each pixel takes the value of the particle whose cell contains the pixel
        smooth                  additionally smooths regions of coarser resolution to reduce 'blockiness'
        level                   each pixel takes the value of the resolution level of the particle cell it belongs to
    """

    # get input APR file path from gui
    io_int = pyapr.filegui.InteractiveIO()
    fpath_apr = io_int.get_apr_file_name()

    # Instantiate APR and particle objects
    parts = pyapr.ShortParticles()
    apr = pyapr.APR()

    # Read APR and particles from file
    pyapr.io.read(fpath_apr, apr, parts)

    # Compute piecewise constant reconstruction
    pc_recon = np.array(pyapr.numerics.reconstruction.recon_pc(apr, parts),
                        copy=False)

    # Compute smooth reconstruction
    smooth_recon = np.array(pyapr.numerics.reconstruction.recon_smooth(
        apr, parts),
                            copy=False)

    # Compute level reconstruction
    level_recon = np.array(pyapr.numerics.reconstruction.recon_level(apr),
                           copy=False)

    # Save the results
    file_name = fpath_apr.split('/')[-1]
    file_name = file_name.split('.')[:-1]
    file_name = '.'.join(file_name)

    save_path = io_int.save_tiff_file_name(file_name +
                                           '_reconstruct_const.tif')
    skio.imsave(save_path, pc_recon, check_contrast=False)

    save_path = io_int.save_tiff_file_name(file_name +
                                           '_reconstruct_smooth.tif')
    skio.imsave(save_path, smooth_recon, check_contrast=False)

    save_path = io_int.save_tiff_file_name(file_name +
                                           '_reconstruct_level.tif')
    skio.imsave(save_path, level_recon, check_contrast=False)
Ejemplo n.º 9
0
def remove_small_holes(apr: pyapr.APR,
                       parts: (pyapr.ShortParticles, pyapr.LongParticles),
                       min_volume: int = 200):

    mask = parts < 1
    cc_inverted = pyapr.ShortParticles()
    pyapr.numerics.segmentation.connected_component(apr, mask, cc_inverted)
    pyapr.numerics.transform.remove_small_objects(apr,
                                                  cc_inverted,
                                                  min_volume=min_volume)
    mask = cc_inverted < 1

    if parts.max() > 1:
        # Case where input is a label map
        if isinstance(parts, pyapr.ShortParticles):
            cc = pyapr.ShortParticles()
        elif isinstance(parts, pyapr.LongParticles):
            mask = np.array(mask).astype('uint16')
            mask = pyapr.ShortParticles(mask)
            cc = pyapr.LongParticles()
        pyapr.numerics.segmentation.connected_component(apr, mask, cc)
        return cc
    else:
        return mask
Ejemplo n.º 10
0
def get_apr(image,
            rel_error=0.1,
            gradient_smoothing=2,
            verbose=True,
            params=None):

    # check that the image array is c-contiguous
    if not image.flags['C_CONTIGUOUS']:
        print(
            'WARNING: \'image\' argument given to get_apr is not C-contiguous \n'
            'input image has been replaced with a C-contiguous copy of itself')
        image = np.ascontiguousarray(image)

    # Initialize objects
    apr = pyapr.APR()

    if params is None:
        par = pyapr.APRParameters()
        par.auto_parameters = True
        par.rel_error = rel_error
        par.gradient_smoothing = gradient_smoothing
    else:
        par = params

    if image.dtype == np.float32:
        parts = pyapr.FloatParticles()
        converter = pyapr.converter.FloatConverter()
    elif image.dtype == np.uint16:
        parts = pyapr.ShortParticles()
        converter = pyapr.converter.ShortConverter()
    # elif image.dtype in {'byte', 'uint8'}:  # currently not working
    #     parts = pyapr.ByteParticles()
    #     converter = pyapr.converter.ByteConverter()
    else:
        errstr = 'pyapr.converter.get_apr: input image dtype must be numpy.uint16 or numpy.float32, ' \
                 'but {} was given'.format(image.dtype)
        raise TypeError(errstr)

    converter.set_parameters(par)
    converter.set_verbose(verbose)

    # Compute the APR and sample particles
    converter.get_apr(apr, image)
    parts.sample_image(apr, image)

    return apr, parts
def main():
    """
    Read a selected APR from file and display (a rectangular region of) a given z-slice as a point scatter.
    """

    # Get APR file path from gui
    io_int = pyapr.filegui.InteractiveIO()
    fpath_apr = io_int.get_apr_file_name()

    # Instantiate APR and particles objects
    apr = pyapr.APR()
    parts = pyapr.ShortParticles()
    # parts = pyapr.FloatParticles()

    # Read APR and particles from file
    pyapr.io.read(fpath_apr, apr, parts)

    display = True  # display the result as a python plot?
    save = False  # save resulting plot as an image?
    if save:
        save_path = io_int.save_tiff_file_name()

    z = None  # which slice to display? (default None -> display center slice)
    base_markersize = 1
    markersize_scale_factor = 2  # markersize = base_markersize * particle_size ** markersize_scale_factor
    figsize = None  # figure size in inches (default None -> determined by xrange, yrange and dpi)
    dpi = 50  # dots per inch (output image dimensions will be dpi*figsize)
    xrange = (400, 800)  # range of x values to be plotted
    yrange = (
        400, 800
    )  # range of y values to be plotted  (if None or out of bounds, the entire range is used)

    pyapr.viewer.particle_scatter_plot(
        apr,
        parts,
        z=z,
        markersize_scale_factor=markersize_scale_factor,
        base_markersize=base_markersize,
        figsize=figsize,
        dpi=dpi,
        save_path=save_path if save else None,
        xrange=xrange,
        yrange=yrange,
        display=display,
        cmap='viridis')
Ejemplo n.º 12
0
def main():
    """
    Read a selected APR from file and display it in the z-slice viewer.
    """

    # Get APR file path from gui
    io_int = pyapr.filegui.InteractiveIO()
    fpath_apr = io_int.get_apr_file_name()

    # Instantiate APR and particles objects
    apr = pyapr.APR()
    parts = pyapr.ShortParticles()
    # parts = pyapr.FloatParticles()

    # Read APR and particles from file
    pyapr.io.read(fpath_apr, apr, parts)

    # Launch the by-slice viewer
    pyapr.viewer.parts_viewer(apr, parts)
Ejemplo n.º 13
0
def main():
    """
    This demo reads an APR, applies a convolution operation and displays the result
    """

    io_int = pyapr.filegui.InteractiveIO()
    fpath_apr = io_int.get_apr_file_name()  # get APR file path from gui

    # Instantiate APR and particle objects
    apr = pyapr.APR()
    parts = pyapr.ShortParticles()  # input particles can be float32 or uint16
    # parts = pyapr.FloatParticles()

    # Read from APR file
    pyapr.io.read(fpath_apr, apr, parts)

    # Stencil and output must be float32
    stencil = pyapr.numerics.filter.get_gaussian_stencil(size=5,
                                                         sigma=1,
                                                         ndims=3,
                                                         normalize=True)
    out = pyapr.FloatParticles()

    # Convolve using CPU:
    pyapr.numerics.convolve(apr,
                            parts,
                            out,
                            stencil,
                            use_stencil_downsample=True,
                            normalize_stencil=True,
                            use_reflective_boundary=False)

    # Alternative CPU convolution method (produces the same result as 'convolve'):
    # pyapr.numerics.convolve_pencil(apr, parts, out, stencil, use_stencil_downsample=True,
    #                                normalize_stencil=True, use_reflective_boundary=False)

    # Convolve using GPU (stencil must be of shape 3x3x3 or 5x5x5):
    # pyapr.numerics.convolve_cuda(apr, parts, out, stencil, use_stencil_downsample=True,
    #                          normalize_stencil=True, use_reflective_boundary=False)

    # Display the result
    pyapr.viewer.parts_viewer(apr, out)
Ejemplo n.º 14
0
def raycast_viewer(apr, parts):

    # Raycast viewer currently only works for ShortParticles
    if isinstance(parts, pyapr.FloatParticles):
        print(
            'Warning: raycast_viewer is currently only implemented for ShortParticles. '
            'Using a uint16 copy of the input particles.')
        parts_short = pyapr.ShortParticles()
        parts_short.copy(parts)
    else:
        parts_short = parts

    pg.setConfigOption('background', 'w')
    pg.setConfigOption('foreground', 'k')
    pg.setConfigOption('imageAxisOrder', 'row-major')

    app = QtGui.QApplication.instance()
    if app is None:
        app = QtGui.QApplication([])

    # Create window with GraphicsView widget
    win = MainWindowImage()
    win.show()
    win.apr_ref = apr
    win.app_ref = app

    raycaster = pyapr.viewer.raycaster()
    raycaster.set_z_anisotropy(1)
    raycaster.set_radius(0.1)

    win.view.setMouseEnabled(False, False)
    win.raycaster_ref = raycaster
    win.raycaster_ref.set_angle(win.current_theta)
    win.raycaster_ref.set_phi(win.current_phi)

    tree_parts = pyapr.FloatParticles()
    pyapr.viewer.get_down_sample_parts(apr, parts, tree_parts)

    win.set_image(apr, parts_short, tree_parts)
    app.exec_()
Ejemplo n.º 15
0
def main():
    """
    Read a selected APR from file and visualize it via maximum intensity projection.

    Scroll to zoom
    Click and drag to change the view
    """

    # Get input APR file path from gui
    io_int = pyapr.filegui.InteractiveIO()
    fpath_apr = io_int.get_apr_file_name()

    # Instantiate APR and particles objects
    apr = pyapr.APR()
    parts = pyapr.ShortParticles()
    # parts = pyapr.FloatParticles()

    # Read APR and particles from file
    pyapr.io.read(fpath_apr, apr, parts)

    # Launch the raycast viewer
    pyapr.viewer.raycast_viewer(apr, parts)
def main():
    """
    This demo applies lossy compression to the particle intensities, with the background level and quantization factor
    set interactively.
    """

    io_int = pyapr.filegui.InteractiveIO()
    fpath_apr = io_int.get_apr_file_name()  # get APR file path from gui

    # Instantiate objects
    apr = pyapr.APR()
    parts = pyapr.ShortParticles()

    # Read APR and particles from file
    pyapr.io.read(fpath_apr, apr, parts)

    # Interactive WNL compression
    pyapr.viewer.interactive_compression(apr, parts)

    # Write compressed APR to file
    fpath_apr_save = io_int.save_apr_file_name()  # get file path from gui
    pyapr.io.write(fpath_apr_save, apr, parts)

    # Size of original and compressed APR files in MB
    original_file_size = os.path.getsize(fpath_apr) * 1e-6
    compressed_file_size = os.path.getsize(fpath_apr_save) * 1e-6

    # Uncompressed pixel image size (assuming 16-bit datatype)
    original_image_size = 2e-6 * apr.x_num(apr.level_max()) * apr.y_num(apr.level_max()) * apr.z_num(apr.level_max())

    print("Original APR File Size: {:7.2f} MB".format(original_file_size))
    print("Lossy Compressed APR File Size: {:7.2f} MB".format(compressed_file_size))

    # compare uncompressed pixel image size to compressed APR file sizes
    print("Original Memory Compression Ratio: {:7.2f} ".format(original_image_size/original_file_size))
    print("Lossy Memory Compression Ratio: {:7.2f} ".format(original_image_size/compressed_file_size))
Ejemplo n.º 17
0
def main():
    """
    This demo performs graph cut segmentation using maxflow-v3.04 (http://pub.ist.ac.at/~vnk/software.html)
    by Yuri Boykov and Vladimir Kolmogorov.

    The graph is formed by linking each particle to its face-side neighbours in each dimension.
    Terminal edge costs are set based on a smoothed local minimum and the local standard deviation, while
    neighbour edge costs are set based on intensity difference, resolution level and local standard deviation.

    Note: experimental!
    """

    io_int = pyapr.filegui.InteractiveIO()
    fpath_apr = io_int.get_apr_file_name()  # get APR file path from gui

    # Instantiate APR and particle objects
    apr = pyapr.APR()
    parts = pyapr.ShortParticles()  # input particles can be float32 or uint16
    # parts = pyapr.FloatParticles()

    # Read from APR file
    pyapr.io.read(fpath_apr, apr, parts)

    # output must be short (uint16)
    mask = pyapr.ShortParticles()

    # parameters affecting memory usage
    avg_num_neighbours = 3.2  # controls the amount of memory initially allocated for edges.
    #                                     if memory is being reallocated, consider increasing this value
    z_block_size = 64  # tiled version only: process chunks of this many z-slices
    z_ghost_size = 16  # tiled version only: use this many "ghost slices" on each side of the chunks

    # parameters affecting the edge costs
    alpha = 5.0  # scaling factor for terminal edges
    beta = 3.0  # scaling factor for neighbour edges

    # parameters affecting the "local minimum" computation
    num_tree_smooth = 3  # number of "neighbour smoothing" iterations to perform on tree particles
    push_depth = 1  # high-resolution nodes take their values from push_depth levels coarser nodes
    num_part_smooth = 3  # number of "neighbour smoothing" iterations to perform on the APR particles

    # additional parameters affecting the costs
    intensity_threshold = 0  # lower threshold on absolute intensity
    std_window_size = 9  # size of the window used to compute the local standard deviation
    min_var = 30  # both terminal costs are set to 0 in regions with std lower than this value
    num_levels = 2  # terminal costs are only set for the num_levels finest resolution particles
    max_factor = 3.0  # particles brighter than "local_min + max_factor * local_std" are considered foreground

    # Compute graphcut segmentation
    pyapr.numerics.segmentation.graphcut(
        apr,
        parts,
        mask,
        alpha=alpha,
        beta=beta,
        avg_num_neighbours=avg_num_neighbours,
        num_tree_smooth=num_tree_smooth,
        num_part_smooth=num_part_smooth,
        push_depth=push_depth,
        intensity_threshold=intensity_threshold,
        min_var=min_var,
        std_window_size=std_window_size,
        max_factor=max_factor,
        num_levels=num_levels)

    # If you run out of memory, try using this version
    # pyapr.numerics.segmentation.graphcut_tiled(apr, parts, mask, alpha=alpha, beta=beta, avg_num_neighbours=avg_num_neighbours,
    #                                            z_block_size=z_block_size, z_ghost_size=z_ghost_size, num_tree_smooth=num_tree_smooth,
    #                                            num_part_smooth=num_part_smooth, push_depth=push_depth, intensity_threshold=intensity_threshold,
    #                                            min_var=min_var, std_window_size=std_window_size,
    #                                            max_factor=max_factor, num_levels=num_levels)

    # Display the result
    pyapr.viewer.parts_viewer(apr, mask)

    # Save the result to hdf5
    save_path = io_int.save_apr_file_name()
    pyapr.io.write(save_path, apr, mask)
Ejemplo n.º 18
0
def main():
    """
    Interactive APR conversion of large images. Reads in a block of z-slices for interactive setting of the
    following parameters:
        Ip_th       (background intensity level)
        sigma_th    (local intensity scale threshold)
        grad_th     (gradient threshold)

    Use the sliders to control the adaptation. The red overlay shows (approximately) the regions that will be fully
    resolved (at pixel resolution).

    Once the parameters are set, the entire image is processed in overlapping blocks of z-slices. The size of the
    blocks, and the overlap, can be set in the code below to control the memory consumption.

    Note: The effect of grad_th may hide the effect of the other thresholds. It is thus recommended to keep grad_th
    low while setting Ip_th and sigma_th, and then increasing grad_th.
    """

    # Read in an image
    io_int = pyapr.filegui.InteractiveIO()
    fpath = io_int.get_tiff_file_name(
    )  # get image file path from gui (data type must be float32 or uint16)

    # Specify the z-range to be used to set the parameters
    z_start = 0
    z_end = 256

    # Read slice range into numpy array
    with tifffile.TiffFile(fpath) as tif:
        img = tif.asarray(key=slice(z_start, z_end))

    # Set some parameters (only Ip_th, grad_th and sigma_th are set interactively)
    par = pyapr.APRParameters()
    par.rel_error = 0.1  # relative error threshold
    par.gradient_smoothing = 3  # b-spline smoothing parameter for gradient estimation
    #                                  0 = no smoothing, higher = more smoothing
    par.dx = 1
    par.dy = 1  # voxel size
    par.dz = 1

    # Interactively set the threshold parameters using the partial image
    par = pyapr.converter.find_parameters_interactive(img,
                                                      params=par,
                                                      verbose=True,
                                                      slider_decimals=1)

    del img  # Parameters found, we don't need the partial image anymore

    # par.input_dir + par.input_image_name must be the path to the image file
    par.input_dir = ''
    par.input_image_name = fpath

    # Initialize the by-block converter
    converter = pyapr.converter.ShortConverterBatch()
    converter.set_parameters(par)
    converter.set_verbose(True)

    # Parameters controlling the memory usage
    converter.set_block_size(
        256
    )  # number of z-slices to process in each block during APR conversion
    converter.set_ghost_size(
        32)  # number of ghost slices to use on each side of the blocks
    block_size_sampling = 256  # block size for sampling of particle intensities
    ghost_size_sampling = 128  # ghost size for sampling of particle intensities

    # Compute the APR
    apr = pyapr.APR()
    success = converter.get_apr(apr)

    if success:
        cr = apr.computational_ratio()
        print(
            'APR Conversion successful! Computational ratio (#pixels / #particles) = {}'
            .format(cr))

        print('Sampling particle intensity values')
        parts = pyapr.ShortParticles()
        parts.sample_image_blocked(apr, fpath, block_size_sampling,
                                   ghost_size_sampling)
        print('Done!')

        # View the result in the by-slice viewer
        pyapr.viewer.parts_viewer(apr, parts)

        # Write the resulting APR to file
        print("Writing APR to file ... \n")
        fpath_apr = io_int.save_apr_file_name()  # get path through gui
        pyapr.io.write(fpath_apr, apr, parts)

        if fpath_apr:
            # Display the size of the file
            file_sz = os.path.getsize(fpath_apr)
            print("APR File Size: {:7.2f} MB \n".format(file_sz * 1e-6))

            # Compute compression ratio
            mcr = os.path.getsize(fpath) / file_sz
            print("Memory Compression Ratio: {:7.2f}".format(mcr))

    else:
        print('Something went wrong...')
def convert_to_apr_point_cloud(fpath_image, fpath_mask):

    img = skio.imread(fpath_image)
    mask = skio.imread(fpath_mask)

    while img.ndim < 3:
        img = np.expand_dims(img, axis=0)

    apr = pyapr.APR()
    parts = pyapr.ShortParticles()
    par = pyapr.APRParameters()
    converter = pyapr.converter.ShortConverter()

    # Initialize APRParameters (only Ip_th, grad_th and sigma_th are set manually)
    par.auto_parameters = False
    par.rel_error = 0.1
    par.gradient_smoothing = 2
    par.min_signal = 200
    par.noise_sd_estimate = 5

    #Setting the APRParameters (only Ip_th, grad_th and sigma_th) using the global values
    par.Ip_th = IP_TH
    par.grad_th = GRAD_TH
    par.sigma_th = SIGMA_TH

    converter.set_parameters(par)
    converter.set_verbose(True)

    # # Compute APR and sample particle values
    converter.get_apr(apr, img)
    parts.sample_image(apr, img)
    # apr, parts = pyapr.converter.get_apr_interactive(img, dtype=img.dtype, params=par, verbose=True)

    # Display the APR
    # pyapr.viewer.parts_viewer(apr, parts)

    # Converting APR into Pointcloud
    org_dims = apr.org_dims()  # (Ny, Nx, Nz)
    #py_recon = np.empty((org_dims[2], org_dims[1], org_dims[0]), dtype=np.uint16)
    max_level = apr.level_max()

    apr_it = apr.iterator()

    v_min = min(parts)
    v_max = max(parts)
    point = []
    for idx, part in enumerate(parts):
        parts[idx] = int(((parts[idx] - v_min) / (v_max - v_min)) * 255)

    # loop over levels up to level_max-1
    for level in range(apr_it.level_min(), apr_it.level_max() + 1):

        step_size = 2**(max_level - level)

        for z in range(apr_it.z_num(level)):
            for x in range(apr_it.x_num(level)):
                for idx in range(apr_it.begin(level, z, x), apr_it.end()):
                    y = apr_it.y(idx)  # this is slow

                    y_start = y * step_size
                    x_start = x * step_size
                    z_start = z * step_size

                    point += [[
                        x_start, y_start, z_start, parts[idx],
                        mask[z_start, x_start, y_start]
                    ]]

    point_cloud = np.array(point)

    # Write the resulting APR to file
    print("Writing Point Cloud to file ... \n")
    start_idx = 8
    if "_2" in fpath_image: start_idx = start_idx + 2
    fpath_pointcloud = "./data/APRPointCloud/test/" + fpath_image[
        -start_idx:-4] + ".txt"
    np.savetxt(fpath_pointcloud, point_cloud, delimiter=',')

    # # Initialize APRFile for I/O
    # aprfile = pyapr.io.APRFile()
    # aprfile.set_read_write_tree(True)

    # # Write APR and particles to file
    # aprfile.open(fpath_apr, 'WRITE')
    # aprfile.write_apr(apr)
    # aprfile.write_particles('particles', parts)

    # # Compute compression and computational ratios
    # file_sz = aprfile.current_file_size_MB()
    # print("APR File Size: {:7.2f} MB \n".format(file_sz))
    # print("Total number of particles: {}".format(apr.total_number_particles()))
    # mcr = os.path.getsize(fpath_image) * 1e-6 / file_sz
    # cr = img.size/apr.total_number_particles()

    # print("Memory Compression Ratio: {:7.2f}".format(mcr))
    # print("Compuational Ratio: {:7.2f}".format(cr))

    # aprfile.close()

    return 0
Ejemplo n.º 20
0
def main():
    """
    This demo implements a piecewise constant reconstruction using the wrapped PyLinearIterator. The Python reconstruction
    is timed and compared to the internal C++ version.

    Note: The current Python reconstruction is very slow and needs to be improved. For now, this demo is best used as a
    coding example of the loop structure to access particles and their spatial properties.
    """

    io_int = pyapr.filegui.InteractiveIO()
    fpath_apr = io_int.get_apr_file_name()  # get APR file path from gui

    # Instantiate APR and particle objects
    parts = pyapr.ShortParticles()
    apr = pyapr.APR()

    # Read from APR file
    pyapr.io.read(fpath_apr, apr, parts)

    # Illustrates the usage of the Python-wrapped linear iterator by computing the piecewise constant reconstruction
    start = time()
    org_dims = apr.org_dims()  # dimension order (y, x, z)
    py_recon = np.empty((org_dims[2], org_dims[1], org_dims[0]),
                        dtype=np.uint16)
    max_level = apr.level_max()

    apr_it = apr.iterator()  # PyLinearIterator

    # particles at the maximum level coincide with pixels
    level = max_level
    for z in range(apr_it.z_num(level)):
        for x in range(apr_it.x_num(level)):
            for idx in range(apr_it.begin(level, z, x), apr_it.end()):
                py_recon[z, x, apr_it.y(idx)] = parts[idx]

    # loop over levels up to level_max-1
    for level in range(apr_it.level_min(), apr_it.level_max()):

        step_size = 2**(
            max_level - level
        )  # this is the size (in pixels) of the particle cells at level

        for z in range(apr_it.z_num(level)):
            for x in range(apr_it.x_num(level)):
                for idx in range(apr_it.begin(level, z, x), apr_it.end()):
                    y = apr_it.y(idx)

                    y_start = y * step_size
                    x_start = x * step_size
                    z_start = z * step_size

                    y_end = min(y_start + step_size, py_recon.shape[2])
                    x_end = min(x_start + step_size, py_recon.shape[1])
                    z_end = min(z_start + step_size, py_recon.shape[0])

                    py_recon[z_start:z_end, x_start:x_end,
                             y_start:y_end] = parts[idx]

    py_time = time() - start
    print('python reconstruction took {} seconds'.format(py_time))

    # Compare to the c++ reconstruction
    start = time()
    tmp = pyapr.numerics.reconstruction.recon_pc(apr, parts)
    cpp_recon = np.array(tmp, copy=False)
    cpp_time = time() - start
    print('c++ reconstruction took {} seconds'.format(cpp_time))
    print('c++ was {} times faster'.format(py_time / cpp_time))

    # check that both methods produce the same results (on a subset of the image if it is larger than 128^3 pixels)
    zm = min(org_dims[2], 128)
    xm = min(org_dims[1], 128)
    ym = min(org_dims[0], 128)

    success = np.allclose(py_recon[:zm, :xm, :ym], cpp_recon[:zm, :xm, :ym])
    if not success:
        print(
            'Python and C++ reconstructions seem to give different results...')
Ejemplo n.º 21
0
def get_apr_interactive(image,
                        rel_error=0.1,
                        gradient_smoothing=2,
                        verbose=True,
                        params=None,
                        slider_decimals=1):

    # check that the image array is c-contiguous
    if not image.flags['C_CONTIGUOUS']:
        print(
            'WARNING: \'image\' argument given to get_apr_interactive is not C-contiguous \n'
            'input image has been replaced with a C-contiguous copy of itself')
        image = np.ascontiguousarray(image)

    while image.ndim < 3:
        image = np.expand_dims(image, axis=0)

    # Initialize objects
    io_int = pyapr.InteractiveIO()
    apr = pyapr.APR()

    if params is None:
        par = pyapr.APRParameters()
        par.auto_parameters = False
        par.rel_error = rel_error
        par.gradient_smoothing = gradient_smoothing
    else:
        par = params

    if image.dtype == np.float32:
        parts = pyapr.FloatParticles()
        converter = pyapr.converter.FloatConverter()
    elif image.dtype == np.uint16:
        parts = pyapr.ShortParticles()
        converter = pyapr.converter.ShortConverter()
    # elif image.dtype in {'byte', 'uint8'}:  # currently not working
    #     parts = pyapr.ByteParticles()
    #     converter = pyapr.converter.ByteConverter()
    else:
        errstr = 'pyapr.converter.get_apr_interactive: input image dtype must be numpy.uint16 or numpy.float32, ' \
                 'but {} was given'.format(image.dtype)
        raise TypeError(errstr)

    converter.set_parameters(par)
    converter.set_verbose(verbose)

    # launch interactive APR converter
    io_int.interactive_apr(converter,
                           apr,
                           image,
                           slider_decimals=slider_decimals)

    if verbose:
        print("Total number of particles: {}".format(
            apr.total_number_particles()))
        print("Number of pixels in original image: {}".format(image.size))
        cr = image.size / apr.total_number_particles()
        print("Compuational Ratio: {:7.2f}".format(cr))

    # sample particles
    parts.sample_image(apr, image)

    return apr, parts