Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Local mean filter of a numpy array with missing data

I'd like to make a local mean filter of an image stored as a numpy array. The image has some missing pixels near the edges, represented with a valid mask (a bool array).

I could use skimage.filters.rank, but my images are outside of the [-1, 1] range, and for some reason scikit-image has that as a requirement.

There's also astropy.convolution, but it interpolates missing data. For a simple mean there's no need to interpolate. Just average only valid pixels. The input and output valid masks are the same.

Simply setting invalid pixels to zero is not an option as it would contaminate valid pixels averages nearby.

There's also this question, but it's not a duplicate since it asks about the more generic convolution (this is just averaging).

like image 429
fouronnes Avatar asked Nov 07 '22 15:11

fouronnes


1 Answers

The approach that @stefan-van-der-walt is referring to, i.e. using a scipy.ndimage.generic_filter together with numpy.nanmean (not optimised for speed yet).

import numpy as np
from scipy.ndimage import generic_filter

def nanmean_filter(input_array, *args, **kwargs):
    """
    Arguments:
    ----------
    input_array : ndarray
        Input array to filter.
    size : scalar or tuple, optional
        See footprint, below
    footprint : array, optional
        Either `size` or `footprint` must be defined.  `size` gives
        the shape that is taken from the input array, at every element
        position, to define the input to the filter function.
        `footprint` is a boolean array that specifies (implicitly) a
        shape, but also which of the elements within this shape will get
        passed to the filter function.  Thus ``size=(n,m)`` is equivalent
        to ``footprint=np.ones((n,m))``.  We adjust `size` to the number
        of dimensions of the input array, so that, if the input array is
        shape (10,10,10), and `size` is 2, then the actual size used is
        (2,2,2).
    output : array, optional
        The `output` parameter passes an array in which to store the
        filter output. Output array should have different name as compared
        to input array to avoid aliasing errors.
    mode : {'reflect', 'constant', 'nearest', 'mirror', 'wrap'}, optional
        The `mode` parameter determines how the array borders are
        handled, where `cval` is the value when mode is equal to
        'constant'. Default is 'reflect'
    cval : scalar, optional
        Value to fill past edges of input if `mode` is 'constant'. Default
        is 0.0
    origin : scalar, optional
        The `origin` parameter controls the placement of the filter.
        Default 0.0.

    See also:
    ---------
    scipy.ndimage.generic_filter
    """
    return generic_filter(input_array, function=np.nanmean, *args, **kwargs)
like image 167
Paul Brodersen Avatar answered Nov 14 '22 20:11

Paul Brodersen