コード例 #1
0
def main():
    args = parse_args()
    syris.init(device_index=0)
    m = 20

    if args.input == 'grid':
        image = make_grid(args.n, m * q.m).thickness.get()
    elif args.input == 'lena':
        from scipy.misc import lena
        image = lena().astype(cfg.PRECISION.np_float)
        if args.n != image.shape[0]:
            image = gutil.get_host(ip.rescale(image, (args.n, args.n)))

    n = image.shape[0]
    crop_n = n - 2 * m - 2
    y, x = np.mgrid[-n / 2:n / 2, -n / 2:n / 2]
    # Compute a such that the disk diameter is exactly the period when distance from the middle is n
    # / 2
    a = m / (2 * (crop_n / 2.)**2)
    radii = (a * np.sqrt(x**2 + y**2)**2 + 1e-3).astype(cfg.PRECISION.np_float)
    x_param = radii
    y_param = radii

    result = ip.varconvolve_disk(image, (y_param, x_param)).get()
    result = ip.crop(result, (m - 1, m - 1, crop_n, crop_n)).get()
    radii = ip.crop(radii, (m - 1, m - 1, crop_n, crop_n)).get()
    image = ip.crop(image, (m - 1, m - 1, crop_n, crop_n)).get()

    if args.output:
        save_image(args.output, result)

    show(image, title='Original Image')
    show(2 * radii, title='Blurring Disk Diameters')
    show(result, title='Blurred Image')
    plt.show()
コード例 #2
0
ファイル: varconvolution.py プロジェクト: ufo-kit/syris
def main():
    args = parse_args()
    syris.init(device_index=0)
    m = 20

    if args.input == 'grid':
        image = make_grid(args.n, m * q.m).thickness.get()
    elif args.input == 'lena':
        from scipy.misc import lena
        image = lena().astype(cfg.PRECISION.np_float)
        if args.n != image.shape[0]:
            image = gutil.get_host(ip.rescale(image, (args.n, args.n)))

    n = image.shape[0]
    crop_n = n - 2 * m - 2
    y, x = np.mgrid[-n / 2:n / 2, -n / 2:n / 2]
    # Compute a such that the disk diameter is exactly the period when distance from the middle is n
    # / 2
    a = m / (2 * (crop_n / 2.) ** 2)
    radii = (a * np.sqrt(x ** 2 + y ** 2) ** 2 + 1e-3).astype(cfg.PRECISION.np_float)
    x_param = radii
    y_param = radii

    result = ip.varconvolve_disk(image, (y_param, x_param)).get()
    result = ip.crop(result, (m - 1, m - 1, crop_n, crop_n)).get()
    radii = ip.crop(radii, (m - 1, m - 1, crop_n, crop_n)).get()
    image = ip.crop(image, (m - 1, m - 1, crop_n, crop_n)).get()

    if args.output:
        save_image(args.output, result)

    show(image, title='Original Image')
    show(2 * radii, title='Blurring Disk Diameters')
    show(result, title='Blurred Image')
    plt.show()
コード例 #3
0
def main():
    """Main function."""
    args = parse_args()
    syris.init(loglevel=logging.INFO, double_precision=args.double_precision)
    units = q.Quantity(1, args.units)
    triangles = make_cube(
    ).magnitude if args.input is None else read_blender_obj(args.input)
    triangles = triangles * units
    tr = geom.Trajectory([(0, 0, 0)] * units)
    mesh = Mesh(triangles,
                tr,
                center=args.center,
                iterations=args.supersampling)
    LOG.info('Number of triangles: {}'.format(mesh.num_triangles))

    shape = (args.n, args.n)
    if args.pixel_size is None:
        if args.input is None:
            fov = 4. * units
        else:
            # Maximum sample size in x and y direction
            max_diff = np.max(mesh.extrema[:-1, 1] - mesh.extrema[:-1, 0])
            fov = max_diff
        fov *= args.margin
        args.pixel_size = fov / args.n
    else:
        fov = args.n * args.pixel_size

    if args.translate is None:
        translate = (fov.simplified.magnitude / 2.,
                     fov.simplified.magnitude / 2., 0) * q.m
    else:
        translate = (args.translate[0].simplified.magnitude,
                     args.translate[1].simplified.magnitude, 0) * q.m
    LOG.info('Translation: {}'.format(translate.rescale(q.um)))

    mesh.translate(translate)
    mesh.rotate(args.y_rotate, geom.Y_AX)
    mesh.rotate(args.x_rotate, geom.X_AX)
    fmt = 'n: {}, pixel size: {}, FOV: {}'
    LOG.info(
        fmt.format(args.n, args.pixel_size.rescale(q.um), fov.rescale(q.um)))

    st = time.time()
    proj = mesh.project(shape, args.pixel_size, t=None).get()
    LOG.info('Duration: {} s'.format(time.time() - st))
    offset = (0, translate[1].simplified, -(fov / 2.).simplified) * q.m

    if args.projection_filename is not None:
        save_image(args.projection_filename, proj)

    if args.compute_slice:
        sl = mesh.compute_slices((1, ) + shape, args.pixel_size,
                                 offset=offset).get()[0]
        if args.slice_filename is not None:
            save_image(args.slice_filename, sl)
        show(sl, title='Slice at y = {}'.format(args.n / 2))

    show(proj, title='Projection')
    plt.show()
コード例 #4
0
ファイル: mesh_scan.py プロジェクト: ufo-kit/syris
def scan(shape, ps, axis, mesh, angles, prefix, lamino_angle=45 * q.deg, index=0, num_devices=1,
         shift_coeff=1e4, ss=1):
    """Make a scan of tomographic angles. *shift_coeff* is the coefficient multiplied by pixel size
    which shifts the triangles to get rid of faulty pixels.
    """
    psm = ps.simplified.magnitude
    log_fmt = '{}: {:>04}/{:>04} in {:6.2f} s, angle: {:>6.2f} deg, maxima: {}'

    # Move to the middle of the FOV
    point = (shape[1] * psm / 2, shape[0] * psm / 2, 0) * q.m
    if index == 0:
        LOG.info('Mesh shift: {}'.format(point.rescale(q.um)))
        LOG.info('Mesh shift in pixels: {}'.format((point / ps).simplified.magnitude))

    # Compute this device portion of tomographic angles
    enumerated = list(enumerate(angles))
    num_angles = len(enumerated)
    per_device = num_angles / num_devices
    stop = None if index == num_devices - 1 else (index + 1) * per_device
    mine = enumerated[index * per_device:stop]

    last = None
    # Projections which metric exceeds allowed limit
    checked_indices = []
    # Projections which exceed the allowed metric difference even after more iterations
    bad_indices = []
    for i, angle in mine:
        st = time.time()
        projs = [make_projection(shape, ps, axis, mesh, point, lamino_angle, angle, ss=ss)]
        max_vals = [projs[-1].max()]
        best = 0
        if last is not None and max_vals[0] > 2 * last or np.isnan(max_vals[0]):
            # Check for faulty pixels
            checked_indices.append(i)
            for shift in [-psm / shift_coeff, psm / shift_coeff]:
                shifted_point = point + (shift, 0, 0) * q.m
                projs.append(make_projection(shape, ps, axis, mesh, shifted_point,
                                             lamino_angle, angle, ss=ss))
                max_vals.append(projs[-1].max())
            best = np.argmin(max_vals)
            if max_vals[best] > 2 * last or np.isnan(max_vals[best]):
                bad_indices.append(i)
        duration = time.time() - st
        with LOCK:
            LOG.info(log_fmt.format(index, i + 1, num_angles, duration,
                                    float(angle.magnitude), max_vals))
        save_image(prefix.format(i), projs[best][2048-128:2048+128, :])
        last = max_vals[best]

    with LOCK:
        LOG.info('Checked indices: {}'.format(checked_indices))
        LOG.info('Which map to files: {}'.format([prefix.format(i) for i in checked_indices]))
        LOG.info('Exceeding indices: {}'.format(bad_indices))
        LOG.info('Which map to files: {}'.format([prefix.format(i) for i in bad_indices]))

    return projs[best]
コード例 #5
0
ファイル: mesh_scan.py プロジェクト: flmiot/syris-1
def make_ground_truth(args, shape, mesh):
    """Shape is (y, x), so the total number of slices is y."""
    import syris.config as cfg
    from syris.imageprocessing import bin_image

    if args.z_chunk % args.supersampling:
        raise ValueError('z_chunk must be dividable by supersampling')

    queue = cfg.OPENCL.queue
    # Move the mesh to the middle
    ps = args.pixel_size / args.supersampling
    psm = ps.simplified.magnitude
    orig_shape = shape
    shape = tuple([n * args.supersampling for n in shape])
    # Make sure the projections are computed with the same x- and y-offsets
    point = (shape[1] * psm / 2, shape[0] * psm / 2, shape[1] * psm / 2) * q.m
    LOG.info('Mesh shift: {}'.format(point.rescale(q.um)))
    LOG.info('Mesh shift in pixels: {}'.format(
        (point / args.pixel_size).simplified.magnitude))
    mesh.translate(point)
    mesh.transform()
    mesh.sort()

    z_stack = np.empty((args.supersampling, ) + orig_shape,
                       dtype=cfg.PRECISION.np_float)

    for i in range(0, shape[0], args.z_chunk):
        end = min(i + args.z_chunk, shape[0])
        offset = (0, i * ps.rescale(q.um).magnitude, 0) * q.um
        slices = mesh.compute_slices((end - i, ) + shape, ps,
                                     offset=offset).get()
        LOG.info('Computing slices {}-{}'.format(i, end))
        enumerated = list(enumerate(slices))[::args.supersampling]
        for j, sl in enumerated:
            # Z-dimension downsampling
            for k in range(args.supersampling):
                z_stack[k] = bin_image(slices[j + k],
                                       orig_shape,
                                       average=True,
                                       queue=queue).get()
            # Sum only the slices which are present (last run might not go to the end)
            sl = np.mean(z_stack[:slices.shape[0]], axis=0)
            index = (i + j) / args.supersampling
            save_image(args.prefix.format(index), sl)

    return sl
コード例 #6
0
ファイル: mesh_scan.py プロジェクト: ufo-kit/syris
def make_ground_truth(args, shape, mesh):
    """Shape is (y, x), so the total number of slices is y."""
    import syris.config as cfg
    from syris.imageprocessing import bin_image

    if args.z_chunk % args.supersampling:
        raise ValueError('z_chunk must be dividable by supersampling')

    queue = cfg.OPENCL.queue
    # Move the mesh to the middle
    ps = args.pixel_size / args.supersampling
    psm = ps.simplified.magnitude
    orig_shape = shape
    shape = tuple([n * args.supersampling for n in shape])
    # Make sure the projections are computed with the same x- and y-offsets
    point = (shape[1] * psm / 2, shape[0] * psm / 2, shape[1] * psm / 2) * q.m
    LOG.info('Mesh shift: {}'.format(point.rescale(q.um)))
    LOG.info('Mesh shift in pixels: {}'.format((point / args.pixel_size).simplified.magnitude))
    mesh.translate(point)
    mesh.transform()
    mesh.sort()

    z_stack = np.empty((args.supersampling,) + orig_shape, dtype=cfg.PRECISION.np_float)

    for i in range(0, shape[0], args.z_chunk):
        end = min(i + args.z_chunk, shape[0])
        offset = (0, i * ps.rescale(q.um).magnitude, 0) * q.um
        slices = mesh.compute_slices((end - i,) + shape, ps, offset=offset).get()
        LOG.info('Computing slices {}-{}'.format(i, end))
        enumerated = list(enumerate(slices))[::args.supersampling]
        for j, sl in enumerated:
            # Z-dimension downsampling
            for k in range(args.supersampling):
                z_stack[k] = bin_image(slices[j + k], orig_shape, average=True, queue=queue).get()
            # Sum only the slices which are present (last run might not go to the end)
            sl = np.mean(z_stack[:slices.shape[0]], axis=0)
            index = (i + j) / args.supersampling
            save_image(args.prefix.format(index), sl)

    return sl
コード例 #7
0
ファイル: metaballs.py プロジェクト: flmiot/syris-1
def main():
    args = parse_args()
    syris.init(device_index=0)
    shape = (args.n, args.n)
    pixel_size = 1 * q.um

    if args.method == 'random':
        # Random metaballs creation
        metaballs, objects_all = create_metaballs_random(args.n, pixel_size, args.num,
                                                         args.min_radius, args.max_radius)
    elif args.method == 'file':
        # 1e6 because packing converts to meters
        values = np.fromfile(args.input, dtype=np.float32) * 1e6
        metaballs, objects_all = create_metaballs(values.reshape(len(values) / 4, 4))
    else:
        distance = args.distance or args.n / 4
        positions = [(args.n / 2 - distance, args.n / 2, 0, args.n / 6),
                     (args.n / 2 + distance, args.n / 2, 0, args.n / 6)]
        metaballs, objects_all = create_metaballs(positions)

    if args.output:
        with open(args.output, mode='wb') as out_file:
            out_file.write(objects_all)

    z_min, z_max = get_z_range(metaballs)
    print 'z min, max:', z_min.rescale(q.um), z_max.rescale(q.um), args.n * pixel_size + z_min

    if args.algorithm == 'fast':
        traj = Trajectory([(0, 0, 0)] * q.m)
        comp = MetaBalls(traj, metaballs)
        thickness = comp.project(shape, pixel_size).get()
    else:
        print 'Z steps:', int(((z_max - z_min) / pixel_size).simplified.magnitude + 0.5)
        thickness = project_metaballs_naive(metaballs, shape, make_tuple(pixel_size)).get()

    if args.output_thickness:
        save_image(args.output_thickness, thickness)

    show(thickness)
    plt.show()
コード例 #8
0
ファイル: imageprocessing.py プロジェクト: flmiot/syris-1
def save_tiles(prefix, tiles):
    """Save *tiles* to linearly indexed files formed by *prefix* and the tile number."""
    for i, tile in enumerate(tiles):
        save_image(prefix.format(i), tile)
コード例 #9
0
ファイル: mesh_scan.py プロジェクト: flmiot/syris-1
def scan(shape,
         ps,
         axis,
         mesh,
         angles,
         prefix,
         lamino_angle=45 * q.deg,
         index=0,
         num_devices=1,
         shift_coeff=1e4,
         ss=1):
    """Make a scan of tomographic angles. *shift_coeff* is the coefficient multiplied by pixel size
    which shifts the triangles to get rid of faulty pixels.
    """
    psm = ps.simplified.magnitude
    log_fmt = '{}: {:>04}/{:>04} in {:6.2f} s, angle: {:>6.2f} deg, maxima: {}'

    # Move to the middle of the FOV
    point = (shape[1] * psm / 2, shape[0] * psm / 2, 0) * q.m
    if index == 0:
        LOG.info('Mesh shift: {}'.format(point.rescale(q.um)))
        LOG.info('Mesh shift in pixels: {}'.format(
            (point / ps).simplified.magnitude))

    # Compute this device portion of tomographic angles
    enumerated = list(enumerate(angles))
    num_angles = len(enumerated)
    per_device = num_angles / num_devices
    stop = None if index == num_devices - 1 else (index + 1) * per_device
    mine = enumerated[index * per_device:stop]

    last = None
    # Projections which metric exceeds allowed limit
    checked_indices = []
    # Projections which exceed the allowed metric difference even after more iterations
    bad_indices = []
    for i, angle in mine:
        st = time.time()
        projs = [
            make_projection(shape,
                            ps,
                            axis,
                            mesh,
                            point,
                            lamino_angle,
                            angle,
                            ss=ss)
        ]
        max_vals = [projs[-1].max()]
        best = 0
        if last is not None and max_vals[0] > 2 * last or np.isnan(
                max_vals[0]):
            # Check for faulty pixels
            checked_indices.append(i)
            for shift in [-psm / shift_coeff, psm / shift_coeff]:
                shifted_point = point + (shift, 0, 0) * q.m
                projs.append(
                    make_projection(shape,
                                    ps,
                                    axis,
                                    mesh,
                                    shifted_point,
                                    lamino_angle,
                                    angle,
                                    ss=ss))
                max_vals.append(projs[-1].max())
            best = np.argmin(max_vals)
            if max_vals[best] > 2 * last or np.isnan(max_vals[best]):
                bad_indices.append(i)
        duration = time.time() - st
        with LOCK:
            LOG.info(
                log_fmt.format(index, i + 1, num_angles, duration,
                               float(angle.magnitude), max_vals))
        save_image(prefix.format(i), projs[best][2048 - 128:2048 + 128, :])
        last = max_vals[best]

    with LOCK:
        LOG.info('Checked indices: {}'.format(checked_indices))
        LOG.info('Which map to files: {}'.format(
            [prefix.format(i) for i in checked_indices]))
        LOG.info('Exceeding indices: {}'.format(bad_indices))
        LOG.info('Which map to files: {}'.format(
            [prefix.format(i) for i in bad_indices]))

    return projs[best]