| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- import numpy as np
- from ..util import view_as_blocks
- def block_reduce(image, block_size=2, func=np.sum, cval=0, func_kwargs=None):
- """Downsample image by applying function `func` to local blocks.
- This function is useful for max and mean pooling, for example.
- Parameters
- ----------
- image : (M[, ...]) ndarray
- N-dimensional input image.
- block_size : array_like or int
- Array containing down-sampling integer factor along each axis.
- Default block_size is 2.
- func : callable
- Function object which is used to calculate the return value for each
- local block. This function must implement an ``axis`` parameter.
- Primary functions are ``numpy.sum``, ``numpy.min``, ``numpy.max``,
- ``numpy.mean`` and ``numpy.median``. See also `func_kwargs`.
- cval : float
- Constant padding value if image is not perfectly divisible by the
- block size.
- func_kwargs : dict
- Keyword arguments passed to `func`. Notably useful for passing dtype
- argument to ``np.mean``. Takes dictionary of inputs, e.g.:
- ``func_kwargs={'dtype': np.float16})``.
- Returns
- -------
- image : ndarray
- Down-sampled image with same number of dimensions as input image.
- Examples
- --------
- >>> from skimage.measure import block_reduce
- >>> image = np.arange(3*3*4).reshape(3, 3, 4)
- >>> image # doctest: +NORMALIZE_WHITESPACE
- array([[[ 0, 1, 2, 3],
- [ 4, 5, 6, 7],
- [ 8, 9, 10, 11]],
- [[12, 13, 14, 15],
- [16, 17, 18, 19],
- [20, 21, 22, 23]],
- [[24, 25, 26, 27],
- [28, 29, 30, 31],
- [32, 33, 34, 35]]])
- >>> block_reduce(image, block_size=(3, 3, 1), func=np.mean)
- array([[[16., 17., 18., 19.]]])
- >>> image_max1 = block_reduce(image, block_size=(1, 3, 4), func=np.max)
- >>> image_max1 # doctest: +NORMALIZE_WHITESPACE
- array([[[11]],
- [[23]],
- [[35]]])
- >>> image_max2 = block_reduce(image, block_size=(3, 1, 4), func=np.max)
- >>> image_max2 # doctest: +NORMALIZE_WHITESPACE
- array([[[27],
- [31],
- [35]]])
- """
- if np.isscalar(block_size):
- block_size = (block_size,) * image.ndim
- elif len(block_size) != image.ndim:
- raise ValueError(
- "`block_size` must be a scalar or have " "the same length as `image.shape`"
- )
- if func_kwargs is None:
- func_kwargs = {}
- pad_width = []
- for i in range(len(block_size)):
- if block_size[i] < 1:
- raise ValueError(
- "Down-sampling factors must be >= 1. Use "
- "`skimage.transform.resize` to up-sample an "
- "image."
- )
- if image.shape[i] % block_size[i] != 0:
- after_width = block_size[i] - (image.shape[i] % block_size[i])
- else:
- after_width = 0
- pad_width.append((0, after_width))
- if np.any(np.asarray(pad_width)):
- image = np.pad(
- image, pad_width=pad_width, mode='constant', constant_values=cval
- )
- blocked = view_as_blocks(image, block_size)
- return func(blocked, axis=tuple(range(image.ndim, blocked.ndim)), **func_kwargs)
|