def order_filter(a, domain, rank): """Perform an order filter on an N-D array. Perform an order filter on the array in. The domain argument acts as a mask centered over each pixel. The non-zero elements of domain are used to select elements surrounding each input pixel which are placed in a list. The list is sorted, and the output for that pixel is the element corresponding to rank in the sorted list. Args: a (cupy.ndarray): The N-dimensional input array. domain (cupy.ndarray): A mask array with the same number of dimensions as `a`. Each dimension should have an odd number of elements. rank (int): A non-negative integer which selects the element from the sorted list (0 corresponds to the smallest element). Returns: cupy.ndarray: The results of the order filter in an array with the same shape as `a`. .. seealso:: :func:`cupyx.scipy.ndimage.rank_filter` .. seealso:: :func:`scipy.signal.order_filter` """ if a.dtype.kind in 'bc' or a.dtype == cupy.float16: # scipy doesn't support these types raise ValueError("data type not supported") if any(x % 2 != 1 for x in domain.shape): raise ValueError("Each dimension of domain argument " " should have an odd number of elements.") return filters.rank_filter(a, rank, footprint=domain, mode='constant')
def medfilt2d(input, kernel_size=3): """Median filter a 2-dimensional array. Apply a median filter to the `input` array using a local window-size given by `kernel_size` (must be odd). The array is zero-padded automatically. Args: input (cupy.ndarray): A 2-dimensional input array. kernel_size (int of list of ints of length 2): Gives the size of the median filter window in each dimension. Elements of `kernel_size` should be odd. If `kernel_size` is a scalar, then this scalar is used as the size in each dimension. Default is a kernel of size (3, 3). Returns: cupy.ndarray: An array the same size as input containing the median filtered result. See also -------- .. seealso:: :func:`cupyx.scipy.ndimage.median_filter` .. seealso:: :func:`cupyx.scipy.signal.medfilt` .. seealso:: :func:`scipy.signal.medfilt2d` """ if input.dtype not in (cupy.uint8, cupy.float32, cupy.float64): # Scipy's version only supports uint8, float32, and float64 raise ValueError("only supports uint8, float32, and float64") if input.ndim != 2: raise ValueError('input must be 2d') kernel_size = _get_kernel_size(kernel_size, input.ndim) order = kernel_size[0] * kernel_size[1] // 2 return filters.rank_filter(input, order, size=kernel_size, mode='constant')
def medfilt(volume, kernel_size=None): """Perform a median filter on an N-dimensional array. Apply a median filter to the input array using a local window-size given by `kernel_size`. The array will automatically be zero-padded. Args: volume (cupy.ndarray): An N-dimensional input array. kernel_size (int or list of ints): Gives the size of the median filter window in each dimension. Elements of `kernel_size` should be odd. If `kernel_size` is a scalar, then this scalar is used as the size in each dimension. Default size is 3 for each dimension. Returns: cupy.ndarray: An array the same size as input containing the median filtered result. .. seealso:: :func:`cupyx.scipy.ndimage.median_filter` .. seealso:: :func:`scipy.signal.medfilt` """ if volume.dtype.kind == 'c': # scipy doesn't support complex raise ValueError("complex types not supported") # output is forced to float64 to match scipy kernel_size = _get_kernel_size(kernel_size, volume.ndim) if any(k > s for k, s in zip(kernel_size, volume.shape)): warnings.warn('kernel_size exceeds volume extent: ' 'volume will be zero-padded') size = internal.prod(kernel_size) return filters.rank_filter(volume, size // 2, size=kernel_size, output=float, mode='constant')