python - Uso eficiente de mĂșltiples numpy slices para recorte de imagen aleatorio
image-processing (1)
Aproveche el método
strided-based
para la extracción eficiente de parches
Podemos aprovechar
np.lib.stride_tricks.as_strided
scikit-image''s view_as_windows
para obtener ventanas deslizantes que serían simplemente
views
en la matriz de entrada y, por lo tanto, no incurrirán en una sobrecarga de memoria adicional y prácticamente gratis.
Seguramente podemos usar
np.lib.stride_tricks.as_strided
directamente, pero el trabajo de configuración requerido es difícil de administrar, especialmente en arreglos con dimensiones más altas.
Si
scikit-image
no está disponible, podemos usar directamente el
source code
que funciona de forma independiente.
Explicación sobre el uso de
view_as_windows
La idea con
view_as_windows
es que
view_as_windows
en la entrada arg
window_shape
como una tupla de longitud igual a la cantidad de dimensiones en la matriz de entrada cuyas ventanas deslizantes son necesarias.
Los ejes a lo largo de los cuales debemos deslizarnos se alimentan con las longitudes de ventana respectivas y el resto se alimenta con
1s
.
Esto crearía una matriz de
views
con
singleton dims/axes
es decir, ejes con
lengths=1
correspondientes a los
1s
en
window_shape
arg.
Por lo tanto, para esos casos podríamos querer indexar en el elemento cero correspondiente a los ejes que se alimentan como longitudes de las ventanas deslizantes para tener una versión
comprimida
de las ventanas deslizantes.
Por lo tanto, tendríamos una solución, como tal -
# 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)
Tengo una matriz numpy 4-D, con la primera dimensión que representa el número de imágenes en un conjunto de datos, la segunda y la tercera son la anchura y la altura (iguales) y la cuarta la cantidad de canales (3). Por ejemplo, digamos que tengo 4 imágenes en color que son 28 * 28, por lo que mis datos de imagen se ven así:
X = np.reshape(np.arange(4*28*28*3), (4,28,28,3))
Me gustaría seleccionar un recorte aleatorio de 16 * 16 de ancho x alto de cada una de las 4 imágenes. Críticamente, quiero que el recorte sea diferente por imagen, es decir, quiero generar 4 pares aleatorios (x_offset, y_offset). Al final quiero acceder a un conjunto de formas (4, 16, 16, 3).
Si tuviera que escribir esto en un bucle for, se vería algo así:
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
Pero me gustaría hacerlo de la manera más eficiente posible y me pregunto si hay una manera de hacerlo con zancadas e indexación elegante. He visto las respuestas a this pregunta, pero no puedo comprender cómo podría combinar algo como stride_tricks con puntos de inicio aleatorios para los pasos en el segundo y tercer eje (ancho y alto).