user9703439
user9703439

Reputation:

View an image of size (4, 6, 6) with moving window of size (4, 3, 3)

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

Answers (2)

Tonechas
Tonechas

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 forloops 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

B. M.
B. M.

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

Related Questions