def close_binary(img_binary, k=5, plot=True, verbose=True):
    if verbose:
        print('\t - Closing holes with disk of radius %d' % k)
    opened = closing(img_binary, disk(k))
    if plot:
        d.compare2(img_binary, opened, 'Closing: k = %d' % k)
    return opened
def open_binary(img_binary, k=5, plot=True, verbose=True):
    if verbose:
        print('\t - Removing artifacts with disk of radius %d' % k)
    opened = opening(img_binary, disk(k))
    if plot:
        d.compare2(img_binary, opened, 'Opening: k = %d' % k)
    return opened
def distance_transform(img_binary, plot=True, verbose=True):
    if verbose:
        print('\t - Calculating euclidean distance transform')
    img_dist = ndi.distance_transform_edt(img_binary)

    if plot:
        d.compare2(img_binary, img_dist, 'Euclidean Distance Transform')

    return img_dist
def skeleton(img_binary, plot=True, verbose=True):
    if verbose:
        print('\t - Thinning to skeleton')
    img_skel = skeletonize(img_binary, method='lee')

    if plot:
        d.compare2(img_binary, dilation(img_skel),
                   'Skeletonization (image dilated for viewing)')

    img_skel = img_skel / np.amax(img_skel)

    return img_skel
def black_top_hat(image, k=2, plot=False, verbose=True):
    if verbose:
        print('\t - Removing black holes using disk of radius %d' % k)
    res = black_tophat(image, disk(k))
    if plot:
        d.compare3(image,
                   res,
                   image + res,
                   title1='Original',
                   title2='Black Top Hat',
                   title3='Complimentary')

    return image + res
def white_top_hat(image, k=2, plot=False, verbose=True):
    if verbose:
        print('\t - Removing white peaks using disk of radius %d' % k)
    res = white_tophat(image, disk(k))
    if plot:
        d.compare3(image,
                   res,
                   image - res,
                   title1='Original',
                   title2='White Top Hat',
                   title3='Complimentary')

    return image - res
def contrasts(img, plot=True, adpt=0.04):
    # Contrast stretching
    p2, p98 = np.percentile(img, (2, 98))
    img_rescale = exposure.rescale_intensity(img, in_range=(p2, p98))

    # Equalization
    img_eq = exposure.equalize_hist(img)

    # Adaptive Equalization
    img_adapteq = exposure.equalize_adapthist(img, clip_limit=adpt)

    if plot:
        # Display results
        fig = plt.figure(figsize=(15, 15))
        axes = np.zeros((2, 4), dtype=np.object)
        axes[0, 0] = fig.add_subplot(2, 4, 1)
        for i in range(1, 4):
            axes[0, i] = fig.add_subplot(2,
                                         4,
                                         1 + i,
                                         sharex=axes[0, 0],
                                         sharey=axes[0, 0])
        for i in range(0, 4):
            axes[1, i] = fig.add_subplot(2, 4, 5 + i)

        ax_img, ax_hist, ax_cdf = d.plot_img_and_hist(img, axes[:, 0])
        ax_img.set_title('Original image')

        y_min, y_max = ax_hist.get_ylim()
        ax_hist.set_ylabel('Number of pixels')
        ax_hist.set_yticks(np.linspace(0, y_max, 5))

        ax_img, ax_hist, ax_cdf = d.plot_img_and_hist(img_rescale, axes[:, 1])
        ax_img.set_title('Contrast stretching')

        ax_img, ax_hist, ax_cdf = d.plot_img_and_hist(img_eq, axes[:, 2])
        ax_img.set_title('Histogram equalization')

        ax_img, ax_hist, ax_cdf = d.plot_img_and_hist(img_adapteq, axes[:, 3])
        ax_img.set_title('Adaptive equalization')

        ax_cdf.set_ylabel('Fraction of total intensity')
        ax_cdf.set_yticks(np.linspace(0, 1, 5))

        # prevent overlap of y-axis labels
        fig.tight_layout()
        plt.show()

    return img, img_rescale, img_eq, img_adapteq
Beispiel #8
0
def generate_surface(img_3d, iso=0, grad='descent', plot=True, offscreen=False,
                     connected=True, clean=True, fill_internals=False, title=''):
    print('\t - Generating surface mesh')
    verts, faces, normals, values = measure.marching_cubes_lewiner(img_3d, iso, gradient_direction=grad)
    mesh = pymesh.form_mesh(verts, faces)
    vert_list = []
    if clean:
        mesh, vert_list = clean_mesh(mesh, connected=connected, fill_internals=fill_internals)

    verts = mesh.vertices
    faces = mesh.faces
    if plot:
        d.visualize_mesh((verts, faces), offscreen=offscreen, title=title)

    return mesh, vert_list
def background_dilation(image, gauss=1 / 3, plot=True, verbose=True):
    if verbose:
        print(
            '\t - Extracting vessels from background and filtering with sigma=%0.4f'
            % gauss)
    if not gauss:
        return image

    image = img_as_float(image)
    image = gaussian_filter(image, gauss)

    seed = np.copy(image)
    seed[1:-1, 1:-1] = image.min()
    mask = image
    dilated = reconstruction(seed, mask, method='dilation')

    if plot:
        d.compare2(image, dilated, 'Reconstruction via Dilation')

    return dilated
def get_largest_connected_region(img_binary, plot=True, verbose=True):
    if verbose:
        print(' - Retaining only the largest connected region')
    img_lab = measure.label(img_binary, connectivity=2)
    regions = measure.regionprops(img_lab)
    val_max = 0
    label_max = 0
    for props in regions:
        if props.area > val_max:
            val_max = props.area
            label_max = props.label

    img_largest_binary = img_lab == label_max

    if plot:
        d.compare2(img_lab,
                   img_largest_binary,
                   'Largest Connected Region',
                   cmap='magma')

    return img_largest_binary
def std_2d_segment(tif_file, scale_xy, scale_z=1, h_pct=1,
                   contrast_method='rescale', thresh_method='entropy', rwalk_thresh=(0, 0),
                   bth_k=3, wth_k=3, dila_gauss=0.333,
                   open_first=False, open_k=0, close_k=5,
                   connected2D=False,
                   smooth=1, all_plots=True, review_plot=True,
                   output_dir='', name='',
                   save_mask=False, save_skel=False, save_dist=False, save_disp=False, save_review=False,
                   generate_mesh_25=True,
                   connected_mesh=True, connected_vol=False,
                   plot_25d=True, save_volume_mask=True, save_surface_meshes=True, generate_volume_meshes=False):
    img_original = ts(tif_file, page_list=False, flat=True)
    img_original_flat = img_original.get_flat()

    img_dim = img_original_flat.shape
    x_micron = img_original.downsample_factor * scale_xy[0] * img_dim[0]
    y_micron = img_original.downsample_factor * scale_xy[1] * img_dim[1]
    units = np.ceil(max(x_micron, y_micron) / 750)
    img_original.set_units(units)
    scale_xy = (
        img_original.downsample_factor * scale_xy[0] / units, img_original.downsample_factor * scale_xy[1] / units)

    expt_z = len(img_original.get_pages())*scale_z/units
    print('NumPages: %d' % len(img_original.get_pages()))

    enhance_contrasts = st2.contrasts(img_original_flat, plot=all_plots, adpt=0.04)
    img_enhanced = enhance_contrasts[contrasts[contrast_method]]

    print('============')
    print('2d analysis:')
    print('============')

    print(' - Filtering the flattened image')
    img = st2.black_top_hat(img_enhanced, plot=all_plots, k=bth_k)
    img = st2.white_top_hat(img, plot=all_plots, k=wth_k)
    dilated = st2.background_dilation(img, gauss=dila_gauss, plot=all_plots)

    print(' - Converting to binary mask')
    if thresh_method == 'random-walk':
        low = rwalk_thresh[0]
        high = rwalk_thresh[1]
        img_mask = st2.random_walk_thresh(dilated, low, high, plot=all_plots)
    else:
        img_mask = st2.cross_entropy_thresh(dilated, plot=all_plots, verbose=False)

    print(' - Cleaning the binary mask')
    if open_first:
        img_mask = st2.open_binary(img_mask, k=open_k, plot=all_plots)
        img_mask = st2.close_binary(img_mask, k=close_k, plot=all_plots)
    else:
        img_mask = st2.close_binary(img_mask, k=close_k, plot=all_plots)
        img_mask = st2.open_binary(img_mask, k=open_k, plot=all_plots)

    if connected2D:
        img_mask = st2.get_largest_connected_region(img_mask, plot=all_plots)

    if scale_xy[0] != 1 or scale_xy[1] != 1:
        print(' - Scaling to %d um / pixel' % units)
        current_dim = img_mask.shape
        new_dim = (np.round(current_dim[0] * scale_xy[0]), np.round(current_dim[1] * scale_xy[1]))
        img_mask = transform.resize(img_mask, new_dim)
        img_enhanced = transform.resize(img_enhanced, new_dim)

    print('\t - Smoothing mask to reduce skeleton error')
    img_mask = filters.gaussian(img_mask, sigma=(smooth * scale_xy[0] / 3.0, smooth * scale_xy[1] / 3.0),
                                preserve_range=True)

    img_mask = img_mask > np.mean(img_mask)

    print('\t\t - Using smooth=' + str(smooth) +
          ' coresponding to a gaussian filter of sigma=' +
          str('(%0.4f, %0.4f)' % (smooth * scale_xy[0] / 3.0, smooth * scale_xy[0] / 3.0)))

    print(' - Producing computationally useful transforms')
    img_skel = st2.skeleton(img_mask, plot=all_plots)
    img_dist = st2.distance_transform(img_mask, plot=all_plots)

    if all_plots or review_plot:
        d.review_2d_results(img_enhanced, img_mask, dilation(img_skel), img_dist, units=units)

    if save_mask:
        if not os.path.isdir(output_dir + 'masks2D/'):
            os.mkdir(output_dir + 'masks2D/')
        plt.imsave(output_dir + 'masks2D/' + name + ('-%dum-pix' % units) + '.png', img_mask, cmap='gray')

    if save_skel:
        if not os.path.isdir(output_dir + 'skels2D/'):
            os.mkdir(output_dir + 'skels2D/')
        plt.imsave(output_dir + 'skels2D/' + name + ('-%dum-pix' % units) + '.png', img_skel, cmap='gray')

    if save_dist:
        if not os.path.isdir(output_dir + 'distance2D/'):
            os.mkdir(output_dir + 'distance2D/')
        plt.imsave(output_dir + 'distance2D/' + name + ('-%dum-pix' % units) + '.png', img_dist, cmap='gray')

    if save_disp:
        if not os.path.isdir(output_dir + 'display/'):
            os.mkdir(output_dir + 'display/')
        plt.imsave(output_dir + 'display/' + name + ('-%dum-pix' % units) + '.png', img_enhanced, cmap='gray')

    if save_review:
        if not os.path.isdir(output_dir + 'review-segment2D/'):
            os.mkdir(output_dir + 'review-segment2D/')
        d.review_2d_results(img_enhanced, img_mask, dilation(img_skel), img_dist,
                            saving=True, units=units).savefig(
            output_dir + 'review-segment2D/' + name + ('-%dum-pix' % units) + '.png')
        plt.show(block=False)
        plt.close()

    if generate_mesh_25:
        segment_2d_to_meshes(img_dist, img_skel, units=units, h_pct=h_pct, expt_z=expt_z, connected_mesh=connected_mesh,
                             connected_vol=connected_vol,
                             plot_25d=plot_25d,
                             save_volume_mask=save_volume_mask,
                             save_surface_meshes=save_surface_meshes, generate_volume_meshes=generate_volume_meshes,
                             output_dir=output_dir, name=name)

    return img_enhanced, img_mask, img_skel, img_dist, img_original