Reputation:
I wanted to view an image using moving window method, and calculate mean for each window:
import numpy as np
from skimage.util import view_as_windows
image = np.ones((6,6)) # A single channel image
print (image.shape)
(6, 6)
result = view_as_windows(image, window_shape=(3,3), step=1)
print (result.shape)
(4, 4, 3, 3)
mean = np.mean(result, axis=(2,3))
print (mean.shape)
(4, 4)
But could not do it for 3D image.
I wanted to view it with window size of (3, 3) using all channels (4).
image = np.ones((4, 6, 6)) #image with 4 channels
print (image.shape)
(4, 6, 6)
result = view_as_windows(image, window_shape=(4,3,3), step=1)
print (result.shape)
(1, 4, 4, 4, 3, 3)
mean = np.mean(result, axis=(4,5))
print (mean.shape)
(1, 4, 4, 4)
Upvotes: 1
Views: 130
Reputation: 13733
Provided that your image is a 3-D array, view_as_windows
yields a 6-D array. If you want to compute the mean of each window using vectorized code rather than through for
loops you just need to pass the last three axes to NumPy's mean
like this:
In [18]: img = np.ones((4, 6, 6))
In [19]: windows = view_as_windows(image, window_shape=(4, 3, 3), step=1)
In [20]: windows.shape
Out[20]: (1, 4, 4, 4, 3, 3)
In [21]: avg = np.mean(windows, axis=(-1, -2, -3))
In [22]: avg.shape
Out[22]: (1, 4, 4)
In [23]: avg
Out[23]:
array([[[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]]])
Description of parameter axis
from the docs:
axis : None or int or tuple of ints, optional
Axis or axes along which the means are computed. The default is to compute the mean of the flattened array.
New in version 1.7.0.
If this is a tuple of ints, a mean is performed over multiple axes, instead of a single axis or all the axes as before.
Upvotes: 1
Reputation: 18638
you have a trailing dimension here. discard it with :
view_as_windows(image, window_shape=(4,3,3)).squeeze()
then the dimensions will be :
(4, 6, 6)
(4, 4, 4, 3, 3)
(4, 4, 4)
Which I think it's what you want.
Upvotes: 1