def measure_fluorescence(image, worm_mask, well_mask=None):
    if well_mask is not None:
        restricted_mask = ndimage.binary_erosion(well_mask, iterations=15)
        background = polyfit.fit_polynomial(image[::4,::4], mask=restricted_mask[::4,::4], degree=2).astype(numpy.float32)
        background = ndimage.zoom(background, 4)
        background /= background[well_mask].mean()
        background[background <= 0.01] = 1 # we're going to divide by background, so prevent div/0 errors
        image = image.astype(numpy.float32) / background
        image[~well_mask] = 0

    worm_pixels = image[worm_mask]
    low_px_mean, low_px_std = mcd.robust_mean_std(worm_pixels[worm_pixels < worm_pixels.mean()], 0.5)
    expression_thresh = low_px_mean + 2.5*low_px_std
    high_expression_thresh = low_px_mean + 6*low_px_std
    fluo_px = worm_pixels[worm_pixels > expression_thresh]
    high_fluo_px = worm_pixels[worm_pixels > high_expression_thresh]

    area = worm_mask.sum()
    integrated = worm_pixels.sum()
    median, percentile95 = numpy.percentile(worm_pixels, [50, 95])
    expression_area = fluo_px.size
    expression_area_fraction = expression_area / area
    expression_mean = fluo_px.mean()
    high_expression_area = high_fluo_px.size
    high_expression_area_fraction = high_expression_area / area
    high_expression_mean = high_fluo_px.mean()
    high_expression_integrated = high_fluo_px.sum()

    expression_mask = (image > expression_thresh) & worm_mask
    high_expression_mask = (image > high_expression_thresh) & worm_mask

    return data_row(area, integrated, median, percentile95,
     expression_area, expression_area_fraction, expression_mean,
     high_expression_area, high_expression_area_fraction,
     high_expression_mean, high_expression_integrated), (image, background, expression_mask, high_expression_mask)
Beispiel #2
0
def refine_worm(image, initial_area, candidate_edges):
    # find strong worm edges (roughly equivalent to the edges found by find_initial_worm,
    # which are in candidate_edges): smooth the image, do canny edge-finding, and
    # then keep only those edges near candidate_edges
    smooth_image = restoration.denoise_tv_bregman(image, 140).astype(numpy.float32)
    smoothed, gradient, sobel = canny.prepare_canny(smooth_image, 8, initial_area)
    local_maxima = canny.canny_local_maxima(gradient, sobel)
    candidate_edge_region = ndimage.binary_dilation(candidate_edges, iterations=4)
    strong_edges = local_maxima & candidate_edge_region

    # Now threshold the image to find dark blobs as our initial worm region
    # First, find areas in the initial region unlikely to be worm pixels
    mean, std = mcd.robust_mean_std(smooth_image[initial_area][::4], 0.85)
    non_worm = (smooth_image > mean - std) & initial_area
    # now fit a smoothly varying polynomial to the non-worm pixels in the initial
    # region of interest, and subtract that from the actual image to generate
    # an image with a flat illumination field
    background = polyfit.fit_polynomial(smooth_image, mask=non_worm, degree=2)
    minus_bg = smooth_image - background
    # now recalculate a threshold from the background-subtracted pixels
    mean, std = mcd.robust_mean_std(minus_bg[initial_area][::4], 0.85)
    initial_worm = (minus_bg < mean - std) & initial_area
    # Add any pixels near the strong edges to our candidate worm position
    initial_worm |= ndimage.binary_dilation(strong_edges, iterations=3)
    initial_worm = mask.fill_small_radius_holes(initial_worm, 5)

    # Now grow/shrink the initial_worm region so that as many of the strong
    # edges from the canny filter are in contact with the region edges as possible.
    ac = active_contour.EdgeClaimingAdvection(initial_worm, strong_edges,
        max_region_mask=initial_area)
    stopper = active_contour.StoppingCondition(ac, max_iterations=100)
    while stopper.should_continue():
        ac.advect(iters=1)
        ac.smooth(iters=1, depth=2)
    worm_mask = mask.fill_small_radius_holes(ac.mask, 7)

    # Now, get edges from the image at a finer scale
    smoothed, gradient, sobel = canny.prepare_canny(smooth_image, 0.3, initial_area)
    local_maxima = canny.canny_local_maxima(gradient, sobel)
    strong_sum = strong_edges.sum()
    highp = 100 * (1 - 1.5*strong_sum/local_maxima.sum())
    lowp = max(100 * (1 - 3*strong_sum/local_maxima.sum()), 0)
    low_worm, high_worm = numpy.percentile(gradient[local_maxima], [lowp, highp])
    fine_edges = canny.canny_hysteresis(local_maxima, gradient, low_worm, high_worm)

    # Expand out the identified worm area to include any of these finer edges
    closed_edges = ndimage.binary_closing(fine_edges, structure=S)
    worm = ndimage.binary_propagation(worm_mask, mask=worm_mask|closed_edges, structure=S)
    worm = ndimage.binary_closing(worm, structure=S, iterations=2)
    worm = mask.fill_small_radius_holes(worm, 5)
    worm = ndimage.binary_opening(worm)
    worm = mask.get_largest_object(worm)
    # Last, smooth the shape a bit to reduce sharp corners, but not too much to
    # sand off the tail
    ac = active_contour.CurvatureMorphology(worm, max_region_mask=initial_area)
    ac.smooth(depth=2, iters=2)
    return strong_edges, ac.mask