Beispiel #1
0
def _hat_masks(hat_rad, brim_rad):
    """"
    Returns hat and brim boolean masks. brim_rad is from the center, _not_ in addition to hat_rad
    """
    mea = 2 * brim_rad + 1
    hat = imops.generate_circle_mask(hat_rad, mea)
    brim = imops.generate_circle_mask(brim_rad, mea)
    brim = brim & ~hat
    return hat, brim
Beispiel #2
0
    def render(self, im, fl_i, ch_i, cy_i, aln_offset):
        super().render(im, fl_i, ch_i, cy_i, aln_offset)

        blob = imops.generate_circle_mask(self.size, size=self.size * 3)
        imops.accum_inplace(
            im, self.amp * blob, XY(0.25 * im.shape[0], 0.25 * im.shape[0]), center=True
        )
Beispiel #3
0
def _align(cy_ims):
    """
    Align a stack of cy_ims by generating simplified fiducial for each cycle
    (assumes camera does not move between channels)

    Returns:
        aln_offsets: list of YX tuples
        max_score: list of max_score
    """

    kern = _kernel()

    fiducial_ims = []
    for im in cy_ims:
        med = float(np.nanmedian(im))
        im = np.nan_to_num(im, nan=med)
        fiducial_ims += [imops.convolve(im, kern)]
    fiducial_ims = np.array(fiducial_ims) - np.median(fiducial_ims)
    noise_floor = -np.min(fiducial_ims)
    fiducial_ims = np.where(fiducial_ims < noise_floor, 0, 1).astype(np.uint8)

    kern = imops.generate_circle_mask(3).astype(np.uint8)

    fiducial_cy_ims = np.array([
        cv2.dilate(im, kern, iterations=1) for im in fiducial_ims
    ]).astype(float)

    aln_offsets, aln_scores = imops.align(fiducial_cy_ims)
    return aln_offsets, aln_scores
Beispiel #4
0
def _regional_bg_fg_stats(im, mask_radius=2, divs=5, return_ims=False):
    """
    Using an approximate peak kernel, separate FG and BG regionally
    and return the statistics.

    Arguments:
        im: a single frame
        mask_radius:
            Radius in pixels of extra space added around FG candidates
        divs:
            Regional divisions (both horiz and vert)
        return_ims
            If True, also return the fg_im, bg_im
            fg_im will have np.nan in all background spaces
            bg_im will have np.nan in the foreground spaces

    Returns:
        array(divs, divs, 4) with the 4 being: (bg_mean, bg_std, fg_mean, fg_std)
        Optionally returns fg_im, bg_im
    """
    circle = imops.generate_circle_mask(mask_radius).astype(np.uint8)

    kern = _kernel()
    cim = imops.convolve(np.nan_to_num(im, nan=np.nanmedian(im)), kern)

    # cim can end up with artifacts around the nans to the nan_mask
    # is dilated and splated as zeros back over the im
    nan_mask = cv2.dilate(np.isnan(im).astype(np.uint8), circle, iterations=1)

    # The negative side of the convoluted image has no signal
    # so the std of the symetric distribution (reflecting the
    # negative side around zero) is a good estimator of noise.
    if (cim < 0).sum() == 0:
        # Handle the empty case to avoid warning
        thresh = 1e10
    else:
        thresh = np.nanstd(np.concatenate((cim[cim < 0], -cim[cim < 0])))
        thresh = np.nan_to_num(
            thresh, nan=1e10)  # For nan thresh just make them very large
    cim = np.nan_to_num(cim)
    fg_mask = np.where(cim > thresh, 1, 0)

    fg_im = np.where(fg_mask & ~nan_mask, im, np.nan)

    fg_mask = cv2.dilate(fg_mask.astype(np.uint8), circle, iterations=1)
    bg_im = np.where(fg_mask | nan_mask, np.nan, im)

    def nanstats(dat):
        if np.all(np.isnan(dat)):
            return np.nan, np.nan
        return np.nanmean(dat), np.nanstd(dat)

    reg_bg_means, reg_bg_stds = imops.region_map(bg_im, nanstats, divs=divs)
    reg_fg_means, reg_fg_stds = imops.region_map(fg_im, nanstats, divs=divs)
    stats = np.stack((reg_bg_means, reg_bg_stds, reg_fg_means, reg_fg_stds),
                     axis=2)
    if return_ims:
        return stats, fg_im, bg_im
    else:
        return stats
Beispiel #5
0
def circle_locs(im, locs, inner_radius=3, outer_radius=4, fill_mode="nan"):
    """
    Returns a copy of im with circles placed around the locs.

    Arguments
        im: The background image
        locs: Nx2 matrix of peak locations
        circle_radius: Radius of circle to draw
        fill_mode:
            "nan": Use im and overlay with circles of NaNs
            "index": zero for all background and the loc index otherwise
                     (This causes the loss of the 0-th peak)
        style_mode:
            "donut" Draw a 1 pixel donut
            "solid": Draw a filled circle

    This can then be visualized like:
        circle_im = circle_locs(im, locs, fill_mode="nan")
        z.im(circle_im, _nan_color="red")
    """
    mea = (outer_radius + 1) * 2 + 1
    hat = imops.generate_circle_mask(inner_radius, mea)

    brim = imops.generate_circle_mask(outer_radius, mea)
    brim = brim & ~hat

    if fill_mode == "nan":
        circle_im = np.zeros_like(im)
        for loc in locs:
            imops.set_with_mask_in_place(circle_im,
                                         brim,
                                         1,
                                         loc=loc,
                                         center=True)
        return np.where(circle_im == 1, np.nan, im)

    if fill_mode == "index":
        circle_im = np.zeros_like(im)
        for loc_i, loc in enumerate(locs):
            imops.set_with_mask_in_place(circle_im,
                                         brim,
                                         loc_i,
                                         loc=loc,
                                         center=True)
        return circle_im
Beispiel #6
0
 def it_generates_a_circle_mask_with_even_radius():
     circle = imops.generate_circle_mask(2)
     T = True
     F = False
     expected = np.array([
         [F, T, T, T, F],
         [T, T, T, T, T],
         [T, T, T, T, T],
         [T, T, T, T, T],
         [F, T, T, T, F],
     ])
     assert all(circle.flatten() == expected.flatten())
Beispiel #7
0
 def it_generates_a_circle_mask_with_even_radius_embedded_in_larger_dim():
     circle = imops.generate_circle_mask(2, 7)
     T = True
     F = False
     expected = np.array([
         [F, F, F, F, F, F, F],
         [F, F, T, T, T, F, F],
         [F, T, T, T, T, T, F],
         [F, T, T, T, T, T, F],
         [F, T, T, T, T, T, F],
         [F, F, T, T, T, F, F],
         [F, F, F, F, F, F, F],
     ])
     assert all(circle.flatten() == expected.flatten())
Beispiel #8
0
def circle_locs(
    im,
    locs,
    inner_radius=3,
    outer_radius=4,
    fill_mode="nan",
    vals=None,
    keep_mask=None,
    peak_iz=None,
):
    """
    Returns a copy of im with circles placed around the locs.

    Arguments
        im: The background image
        locs: Nx2 matrix of peak locations
        circle_radius: Radius of circle to draw
        fill_mode:
            "nan": Use im and overlay with circles of NaNs
            "index": zero for all background and the loc index otherwise
                     (This causes the loss of the 0-th peak)
            "one": zero on background one on foreground
            "vals": zero on background val[loc_i[ for foreground
            "peak_iz": peak_iz
        style_mode:
            "donut" Draw a 1 pixel donut
            "solid": Draw a filled circle

    Notes:
        This can then be visualized like:
            circle_im = circle_locs(im, locs, fill_mode="nan")
            z.im(circle_im, _nan_color="red")
    """
    n_locs = len(locs)
    if keep_mask is None:
        keep_mask = np.ones((n_locs, ), dtype=bool)

    mea = (outer_radius + 1) * 2 + 1
    hat = imops.generate_circle_mask(inner_radius, mea)
    brim = imops.generate_circle_mask(outer_radius, mea)
    brim = brim & ~hat

    if fill_mode == "nan":
        circle_im = np.zeros_like(im)
        for loc_i, (loc, keep) in enumerate(zip(locs, keep_mask)):
            if keep:
                imops.set_with_mask_in_place(circle_im,
                                             brim,
                                             1,
                                             loc=loc,
                                             center=True)
        return np.where(circle_im == 1, np.nan, im)

    if fill_mode == "index":
        circle_im = np.zeros_like(im)
        for loc_i, (loc, keep) in enumerate(zip(locs, keep_mask)):
            if keep:
                imops.set_with_mask_in_place(circle_im,
                                             brim,
                                             loc_i,
                                             loc=loc,
                                             center=True)
        return circle_im

    if fill_mode == "peak_iz":
        circle_im = np.zeros_like(im)
        for peak_i, loc, keep in zip(peak_iz, locs, keep_mask):
            if keep:
                imops.set_with_mask_in_place(circle_im,
                                             brim,
                                             peak_i,
                                             loc=loc,
                                             center=True)
        return circle_im

    if fill_mode == "one":
        circle_im = np.zeros_like(im)
        for loc_i, (loc, keep) in enumerate(zip(locs, keep_mask)):
            if keep:
                imops.set_with_mask_in_place(circle_im,
                                             brim,
                                             1,
                                             loc=loc,
                                             center=True)
        return circle_im

    if fill_mode == "vals":
        check.array_t(vals, shape=(locs.shape[0], ))
        circle_im = np.zeros_like(im)
        for loc_i, (loc, val, keep) in enumerate(zip(locs, vals, keep_mask)):
            if keep:
                imops.set_with_mask_in_place(circle_im,
                                             brim,
                                             val,
                                             loc=loc,
                                             center=True)
        return circle_im