python - what - Usando eficientemente várias fatias numpy para recorte aleatório de imagens



what is numpy (1)

Alavancar o método strided-based para uma extração de patch eficiente

Nós podemos aproveitar o np.lib.stride_tricks.as_strided baseado scikit-image's view_as_windows para obter janelas deslizantes que seriam apenas views no array de entrada e, portanto, não incorrem em sobrecarga de memória extra e virtualmente livre! Certamente, podemos usar o np.lib.stride_tricks.as_strided diretamente, mas o trabalho de configuração necessário é difícil de gerenciar, especialmente em matrizes com dimensões mais altas. Se scikit-image não estiver disponível, podemos usar diretamente o source code que funciona de forma independente.

Explicação sobre o uso de view_as_windows

A ideia com view_as_windows é que nos alimentamos na entrada arg window_shape como uma tupla de comprimento igual ao número de dimensões na matriz de entrada cujas janelas deslizantes são necessárias. Os eixos ao longo dos quais precisamos deslizar são alimentados com os respectivos comprimentos de janela e o restante é alimentado com 1s . Isso criaria uma matriz de views com singleton dims/axes ou seja, eixos com lengths=1 correspondentes aos 1s em window_shape arg. Assim, para esses casos, poderíamos querer indexar no elemento zeroth correspondente aos eixos que são alimentados como os comprimentos das janelas corrediças para ter uma versão comprimida das janelas deslizantes.

Assim, teríamos uma solução, como assim -

# Get sliding windows
from skimage.util.shape import view_as_windows
w = view_as_windows(X, (1,16,16,1))[...,0,:,:,0]

# Index and get our specific windows
out = w[np.arange(X.shape[0]),x,y]

# If you need those in the same format as in the posted loopy code
out = out.transpose(0,2,3,1)

Eu tenho um array numpy 4-D, com a primeira dimensão representando o número de imagens em um conjunto de dados, o segundo e o terceiro sendo a largura (igual) e a altura, e o quarto sendo o número de canais (3). Por exemplo, digamos que eu tenho 4 imagens coloridas que são 28 * 28, então meus dados de imagem são assim:

X = np.reshape(np.arange(4*28*28*3), (4,28,28,3))

Eu gostaria de selecionar uma colheita aleatória de 16 * 16 de largura x altura de cada uma das 4 imagens. Criticamente, eu quero que o crop seja diferente por imagem, ou seja, eu quero gerar 4 pares aleatórios (x_offset, y_offset). No final, quero ter acesso a uma matriz de formas (4, 16, 16, 3).

Se eu fosse escrever isso em um loop for, seria algo parecido com isto:

x = np.random.randint(0,12,4)
y = np.random.randint(0,12,4)
for i in range(X.shape[0]):
    cropped_image = X[i, x[i]:x[i]+16, y[i]:y[i]+16, :]
    #Add cropped image to a list or something

Mas eu gostaria de fazê-lo da forma mais eficiente possível e estou me perguntando se há uma maneira de fazer isso com strides e indexação sofisticada. Eu vi as respostas para this pergunta, mas não consigo entender como eu poderia combinar algo como stride_tricks com pontos iniciais aleatórios para os passos no segundo e terceiro eixos (largura e altura).





image-processing