简体   繁体   中英

How to crop each element of a numpy array with a window size at the same time without looping over each pixel?

I have a numpy array with a size of 240 x 320 x 3 and I want to use a window (window size ws=5 ) to slide over each pixel and crop out the subarray centered at that pixel. The final output dimension should be 240 x 320 x ws x ws x 3 . So I pad the original array with window size and use for loop to do so.

height = 240
width = 320
image = np.random.rand((height, width, 3))
image = np.pad(image, ((ws//2, ws//2), (ws//2, ws//2), (0, 0)), mode='reflect')
patches = np.zeros((height, width, ws, ws, 3))
for i in range(height):
    for j in range(width):
        patches[i, j] = image[i:i+ws, j:j+ws]

Are there any ways to do the cropping of each pixel at the sample time? Like without using the for loop over each pixel?

You are basically getting sliding windows across the image. We can leverage np.lib.stride_tricks.as_strided based scikit-image's view_as_windows to get sliding windows. More info on use of as_strided based view_as_windows .

from skimage.util.shape import view_as_windows

out = view_as_windows(image,(ws,ws,1)).transpose(0,1,4,3,2,5)[:-1,:-1,...,0]

# Alternatively :
out = view_as_windows(image,(ws,ws,1))[:-1,:-1,...,0].transpose(0,1,4,3,2)

Also note that you are missing out on the last possible window, if you had for i in range(height+1) and for j in range(width+1) . To get the same result with our solution, the last indexing step would modify to [...,0] in place of [:-1,:-1,...,0] , thus giving us -

out = view_as_windows(image,(ws,ws,1))[...,0].transpose(0,1,4,3,2)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM