Esempio n. 1
0
def isnr(images, fill_value=0.0):
    """
    Streaming, pixelwise signal-to-noise ratio (SNR).

    Parameters
    ----------
    images : iterable of ndarray
        These images should represent identical measurements. ``images`` can also be a generator.
    fill_value : float, optional
        Division-by-zero results will be filled with this value.

    Yields
    ------
    snr : `~numpy.ndarray`
        Pixelwise signal-to-noise ratio

    See Also
    --------
    snr_from_collection : pixelwise signal-to-noise ratio from a collection of measurements
    """
    first, images = peek(images)
    snr = np.empty_like(first)

    images1, images2 = itercopy(images, 2)
    for mean, std in zip(imean(images1), istd(images2)):
        valid = std != 0
        snr[valid] = mean[valid] / std[valid]
        snr[np.logical_not(valid)] = fill_value
        yield snr
Esempio n. 2
0
def mask_from_collection(images, px_thresh=(0, 3e4), std_thresh=None):
    """
    Determine binary mask from a set of images. These images should represent identical measurements, e.g. a set
    of diffraction patterns before photoexcitation. Pixels are rejected on the following two criteria:

        * Pixels with a value above a certain threshold or below zero, for any image in the set, are considered dead;
        * Pixels with a cumulative standard deviation above a certain threshold are considered uncertain.

    This function operates in constant-memory; it is therefore safe to use on a large collection
    of images (>10GB).

    Parameters
    ----------
    images : iterable of ndarray
        These images should represent identical measurements. ``images`` can also be a generator.
    px_thresh : float or iterable, optional
        Pixels with a value outside of [``min(px_thresh)``, ``max(px_thresh)``] in any of the images in ``images``
        are rejected. If ``px_thresh`` is a single float, it is assumed to be the maximal intensity, and no lower
        bound is enforced.
    std_thresh : int or float or None, optional
        Standard-deviation threshold. If the standard deviation of a pixel exceeds ``std_thresh``,
        it is rejected. If None (default), a threshold is not enforced.

    Returns
    -------
    mask : `~numpy.ndarray`, dtype bool
        Pixel mask. Pixels where ``mask`` is True are invalid.

    Notes
    -----
    ``numpy.inf`` can be used to have a lower pixel value bound but no upper bound. For example, to
    reject all negative pixels only, set ``px_thresh = (0, numpy.inf)``.
    """
    if isinstance(px_thresh, Iterable):
        min_int, max_int = min(px_thresh), max(px_thresh)
    else:
        min_int, max_int = None, px_thresh

    first, images = peek(images)
    mask = np.zeros_like(first, dtype=bool)  # 0 = False

    if std_thresh is not None:
        images, images_for_std = itercopy(images)
        std_calc = istd(images_for_std)
    else:
        std_calc = repeat(np.inf)

    for image, std in zip(images, std_calc):

        mask[image > max_int] = True

        if std_thresh is not None:
            mask[std > std_thresh] = True

        if min_int is not None:
            mask[image < min_int] = True

    return mask
Esempio n. 3
0
    def test_against_numpy_std(self):
        stream = [np.random.random((16, 7, 3)) for _ in range(10)]
        stack = np.stack(stream, axis=-1)

        with catch_warnings():
            simplefilter("ignore")
            for axis in (0, 1, 2, None):
                for ddof in range(4):
                    with self.subTest("axis = {}, ddof = {}".format(axis, ddof)):
                        from_numpy = np.std(stack, axis=axis, ddof=ddof)
                        from_ivar = last(istd(stream, axis=axis, ddof=ddof))
                        self.assertSequenceEqual(from_numpy.shape, from_ivar.shape)
                        self.assertTrue(np.allclose(from_ivar, from_numpy))
Esempio n. 4
0
    def test_against_numpy_nanstd(self):
        source = [np.random.random((16, 12, 5)) for _ in range(10)]
        for arr in source:
            arr[randint(0, 15), randint(0, 11), randint(0, 4)] = np.nan
        stack = np.stack(source, axis=-1)

        for axis in (0, 1, 2, None):
            for ddof in range(4):
                with self.subTest("axis = {}, ddof = {}".format(axis, ddof)):
                    from_numpy = np.nanstd(stack, axis=axis, ddof=ddof)
                    from_ivar = last(
                        istd(source, axis=axis, ddof=ddof, ignore_nan=True)
                    )
                    self.assertSequenceEqual(from_numpy.shape, from_ivar.shape)
                    self.assertTrue(np.allclose(from_ivar, from_numpy))