Пример #1
0
def extrapolate_head(tck, width_tck, smoothing=None):
    '''Since the width/length splines don't get to the end of the worm,
    try to extrapolate the widths and such to the end of the worm mask

    NOTE: Not really used in the spline-fitting pipeline
    '''
    #get first and last points from the width_tck
    width_ends = interpolate.spline_interpolate(width_tck, 2)
    print(width_ends)
    #calculate new x's and y's that go to the end of the mask
    tmax = tck[0][-1]
    print("tmax: " + str(tmax))
    xys = interpolate.spline_evaluate(
        tck, np.linspace(-width_ends[0], tmax + width_ends[1], 600))
    #print(xys.shape)

    #interpolate the widths so that we can add on the end widths
    #NOTE: end widths will be zero since they are at the end of the mask
    widths = interpolate.spline_interpolate(width_tck, 600)
    new_widths = np.concatenate([[0], widths, [0]])
    #need to generate new x's to use to re-make the width splines with new_widths
    #new endpoint xs need to be reflective of where they are on the centerline
    new_xs = np.concatenate([[-widths[0] / tmax],
                             np.linspace(0, 1, 600), [1 + widths[-1] / tmax]])

    #re-make the splines
    if smoothing is None:
        smoothing = 0.2 * len(new_widths)

    new_tck = interpolate.fit_spline(xys, smoothing=smoothing)

    new_width_tck = interpolate.fit_nonparametric_spline(new_xs,
                                                         new_widths,
                                                         smoothing=smoothing)
    return new_tck, new_width_tck
Пример #2
0
def _detect_edges(image, optocoupler, center_tck, width_tck, image_gamma,
                  downscale, gradient_sigma, sigmoid_midpoint,
                  sigmoid_growth_rate, edge_weight, roughness_penalty,
                  post_smoothing):
    """Trace the edges of a worm and return a new center_tck and width_tck.

    Parameters:
        image: ndarray of the brightfield image
        optocoupler: optocoupler magnification (to correctly calculate the image
            vignette)
        center_tck: spline defining the pose of the worm.
        width_tck: spline defining the distance from centerline to worm edges.
        image_gamma: gamma value for intensity transform to highlight worm edges
        downscale: factor by which to downsample the image
        gradient_sigma: sigma for gaussian gradient to find worm edges
        sigmoid_midpoint: midpoint of edge_highlighting sigmoid function for
            gradient values, expressed as a percentile of the gradient value
            over the whole image. (Somewhere around the 50th percentile
            seems generally good.)
        sigmoid_growth_rate: steepness of the sigmoid function. (The gradient is
            over an image rescaled from 0-1; such images have a max gradient
            in the worm region in the range 0.1-0.2. So the range of the sigmoid
            function is generally 0-0.2 or so; getting a steep curve requires
            growth rates in the 500-1000 range.)
        edge_weight: how much to weight image edge strength vs. distance from
            the average widths in the cost function. (The edge part of the
            cost function goes from 0 to 1, and the distance part goes from
            0 to the maximum pixel distance from the average edge; typically
            15 or so for a 2x downscaled image. So to have both terms equally
            weighted, edge_weight should be around 10-20.)
        roughness_penalty: how much to penalize diagonal steps vs. straight
            steps in the edge tracing (to penalize jagged edges). The penalty
            is multiplicative and scaled by the length of the step: a value of 1
            doesn't penalize diagonal steps, while a value of 2 means that a
            1-pixel-up diagonal step costs 2*sqrt(2) times more.
        post_smoothing: spline smoothing factor for re-fit centerline.

    Returns: (cost_image, new_center_tck, new_width_tck)
        cost_image: image defining the cost function for edge tracing
        new_center_tck: new centerline spline
        new_width_tck: new width spline
    """
    cost_image = get_cost_image(image, optocoupler, image_gamma, center_tck,
                                width_tck, downscale, gradient_sigma,
                                sigmoid_midpoint, sigmoid_growth_rate,
                                edge_weight)

    # trace edges to calculate new centerline and widths
    center_coordinates, widths = edge_coordinates(cost_image,
                                                  roughness_penalty)
    lab_center_coordinates = worm_spline.coordinates_to_lab_frame(
        center_coordinates, cost_image.shape, center_tck, zoom=1 / downscale)
    new_center_tck = interpolate.fit_spline(lab_center_coordinates,
                                            smoothing=post_smoothing *
                                            len(lab_center_coordinates))
    x = numpy.linspace(0, 1, len(widths))
    # NB: expand widths to account for downsampling
    new_width_tck = interpolate.fit_nonparametric_spline(
        x, widths * downscale, smoothing=post_smoothing * len(widths))
    return cost_image, new_center_tck, new_width_tck
Пример #3
0
def generate_width_from_pca(projection, pca_stuff):
    '''If you are given a projection from pca (3 components),
    then generate a width_tck from it
    '''
    widths = pca.pca_reconstruct(projection, pcs[:3], mean)
    #make new width spline
    width_tck = interpolate.fit_nonparametric_spline(np.linspace(0,1, len(smoothed_widths)), smoothed_widths)
    return width_tck
Пример #4
0
 def calculate_tck(self, widths, x=None, smoothing=None):
     if x is None:
         x = numpy.linspace(0, 1, len(widths))
     if smoothing is None:
         smoothing = self.REFIT_SMOOTH
     return interpolate.fit_nonparametric_spline(x,
                                                 widths,
                                                 smoothing=smoothing *
                                                 len(widths))
Пример #5
0
 def _smooth_width_from_pca(self, width_tck):
     '''Given a width_tck, use the pca to smooth out the edges
     '''
     #Go from PCA -> real widths and back (real widths -> PCA)
     #Widths -> PCA
     mean, pcs, norm_pcs, variances, total_variance,positions, norm_positions = self.pca_stuff
     widths = interpolate.spline_interpolate(width_tck, 100) 
     projection = pca.pca_decompose(widths, pcs, mean)[:3]
     #PCA -> Widths
     smoothed_widths = pca.pca_reconstruct(projection, pcs[:3], mean)
     #make new width spline
     smoothed_width_tck = interpolate.fit_nonparametric_spline(np.linspace(0,1, len(smoothed_widths)), smoothed_widths)
     return smoothed_width_tck
Пример #6
0
def fit_splines(center_path,
                mask,
                dv_coords,
                width_range=(50, 100),
                width_step=1,
                center_smoothing=0.1,
                width_smoothing=0.0001):
    """Find a (center_tck, width_tck) pose from the centerline path.

    The main challenge is that the dv coordinates are relative to that worm, so an
    absolute scale must be determined. This is done by trying various absolute
    scale factors to find the pixel width of the worm as a function of the dv
    coordinate value along the centerline, and choosing that which best recapitulates
    the mask image provided.

    Parameters:
        center_path: (n, 2)-shape array of coordinates along the centerline of a worm
        mask: approximate mask of worm outline
        dv_coords: dv coordinate image
        width_range: range of possible scale factors to try for the worm (though note that the
            width_tck values are in terms of half-widths from the centerline to the edge)
        width_step: step size for evaluating possible worm widths.
        center_smoothing: average distance the center_tck spline is allowed
            to deviate from the input path coordinates.
        width_smoothing: average distance the width_tck spline is allowed to deviate
            from the input dv coordinate values.

    Returns: (center_tck, width_tck) pose tuple
    """
    center_smoothing *= len(center_path)
    center_tck = interpolate.fit_spline(center_path,
                                        smoothing=center_smoothing,
                                        force_endpoints=False)
    width_profile = dv_coords[tuple(
        center_path.T)] / 6  # scale widths in [0, 0.5] range
    # This range is so that when the width_profile is multiplied by the total worm width, the
    # resulting width_tck will produce the expected half-width distances from centerline to edge
    x = numpy.linspace(0, 1, len(width_profile))
    width_smoothing *= len(width_profile)
    width_profile_tck = interpolate.fit_nonparametric_spline(
        x, width_profile, smoothing=width_smoothing)
    # do coarse / fine search for best width multiplier
    width_tck, max_width = _fit_widths_to_mask(center_tck, width_profile_tck,
                                               width_range, width_step * 4,
                                               mask)
    width_range = max_width - 8 * width_step, max_width + 8 * width_step
    width_tck, max_width = _fit_widths_to_mask(center_tck, width_profile_tck,
                                               width_range, width_step, mask)
    return center_tck, width_tck
Пример #7
0
def generate_width_spline(traceback, shape):
    '''From the traceback, generate a new
    width spline.
    '''
    #since the centerline is at x=0, we just need the
    #y values to get the widths
    _, widths = np.where(traceback)
    widths = shape[1] - widths - 1
    x_vals = np.linspace(0, 1, len(widths))

    smoothing = 0.2 * len(widths)

    tck = interpolate.fit_nonparametric_spline(x_vals,
                                               widths,
                                               smoothing=smoothing)
    return tck
Пример #8
0
def width_spline(traceback, distances, smoothing=None):
    '''Generate a nonparametric spline of the widths along the worm centerline

    Parameters:
    ------------
    traceback: list of 2-d tuples
        List of indices associated with the centerline, starting with
        one of the endpoints of the centerline and ending with the ending
        index of the centerline. 
    distances: ndarray shape(n,m)
        Distance transform from the medial axis transform of the worm mask

    Returns:
    -----------
    tck: nonparametric spline tuple
        spline tuple (see documentation for zplib.interpolate for more info)
    '''
    widths = distances[list(np.transpose(traceback))]
    #print(widths[0])
    #print(widths[-1])

    begin_widths = np.linspace(0, widths[0], widths[0], endpoint=False)
    end_widths = np.linspace(widths[-1] - 1, 0, widths[-1])
    new_widths = np.concatenate((begin_widths, widths, end_widths))
    x_vals = np.linspace(0, 1, len(new_widths))
    #print(x_vals)
    #print(new_widths.shape)
    #print(new_widths)

    if smoothing is None:
        smoothing = 0.2 * len(widths)

    tck = interpolate.fit_nonparametric_spline(x_vals,
                                               new_widths,
                                               smoothing=smoothing)
    return tck
Пример #9
0
def make_unit_worm(metadata, avg_widths, avg_length, image_file, warp_file):
    """Make a unit worm and save the image to the warp_file

        Parameters:
        metadata: dictionary
        avg_widths: array, size (n_points,)
            array of average widths with which to make the worm
        image_file: str;
            what file to use to subsample the textures from 
        warp_file: str;
            where to store the new warp file
    """
    image = freeimage.read(image_file)
    spine_tck = metadata['spine_tck']
    width_tck = metadata['width_tck']
    warp_width = 2 * avg_widths.max() # the worm widths above are from center to edge, so twice that is edge-to-edge
    avg_widths_tck=interpolate.fit_nonparametric_spline(np.linspace(0,1,100),avg_widths)

    warped = resample.warp_image_to_standard_width(image, spine_tck, width_tck, avg_widths_tck, warp_width, length=avg_length)
    #warped = resample.sample_image_along_spline(image, spine_tck, warp_width)
    mask = resample.make_mask_for_sampled_spline(warped.shape[0], warped.shape[1], width_tck)
    warped[~mask] = 0
    print("writing unit worm to :"+str(warp_file))
    freeimage.write(warped, warp_file) # freeimage convention: image.shape = (W, H). So take transpose.
Пример #10
0
 def _to_tck(widths):
     x = numpy.linspace(0, 1, len(widths))
     smoothing = 0.0625 * len(widths)
     return interpolate.fit_nonparametric_spline(x,
                                                 widths,
                                                 smoothing=smoothing)
Пример #11
0
from skimage import graph
from scipy import ndimage
from skimage import feature

import scipy.ndimage as ndimage
import scipy.optimize as optimize

from sklearn.metrics import make_scorer
from sklearn.model_selection import GridSearchCV

import width_finding

mean, pcs, norm_pcs, variances, total_variance, positions, norm_positions = pickle.load(
    open('/mnt/lugia_array/data/human_masks/warped_splines/pca_stuff.p', 'rb'))
avg_width_positions = pca.pca_reconstruct([0, 0, 0], pcs[:3], mean)
avg_width_tck = interpolate.fit_nonparametric_spline(
    np.linspace(0, 1, len(avg_width_positions)), avg_width_positions)


def widths_rmsd(image,
                true_width_tck,
                ggm_sigma=3,
                sig_per=75,
                sig_growth_rate=2,
                alpha=1,
                mcp_alpha=1):
    """Used to optimize the parameters! Wrapper function to generate the widths and then evaluate them
    for the optimization later on
    """
    image_down, traceback = width_finding.find_edges(
        image,
        avg_width_tck,
Пример #12
0
 def _generate_pca_avg(self):
     mean, pcs, norm_pcs, variances, total_variance, positions, norm_positions = self.pca_stuff
     avg_width_positions = pca.pca_reconstruct([0, 0, 0], pcs[:3], mean)
     avg_width_tck = interpolate.fit_nonparametric_spline(
         np.linspace(0, 1, len(avg_width_positions)), avg_width_positions)
     return avg_width_tck
Пример #13
0
    width_points.append(interpolate.spline_interpolate(tck, 100))
width_points
width_points = np.array(width_points)

#PCAAAA
from zplib import pca
mean, pcs, norm_pcs, variances, total_variance, positions, norm_positions = pca.pca_dimensionality_reduce(
    width_points, 0.95)
variances / total_variance
norm_pcs.shape
for std in (-1, 0, 1):
    plt.plot(mean + std * norm_pcs[0])
plt.show()
for std in (-1, 0, 1):
    plt.plot(mean + std * norm_pcs[1])
plt.show()
for std in (-1, 0, 1):
    plt.plot(mean + std * norm_pcs[2])
plt.show()

#From PCA Go back and forth
#Go from PCA -> real widths and back (real widths -> PCA)
#Widths -> PCA
projection = pca.pca_decompose(test_width, pcs, mean)
#PCA -> Widths
test_proj = projection[:3]
positions = pca.pca_reconstruct(test_proj, pcs[:3], mean)
#make new width spline
reverse_width_spline = interpolate.fit_nonparametric_spline(
    np.linspace(0, 1, len(positions)), positions)