Extracción eficiente de la memoria de parches superpuestos de la matriz

cuento:

Esta es una pregunta de seguimiento para: Forma rápida de dividir la imagen en parches superpuestos y fusionar parches a imagen

¿Cómo debo adaptar el código provisto en la respuesta para trabajar no solo en imágenes de tamaño x, y, donde un píxel es descrito por un flotador, sino descrito por una matriz de tamaño 3,3?

Además, ¿cómo adaptar el código para que devuelva un generador que me permita recorrer todos los parches sin tener que guardarlos todos en la memoria?

larga historia:

    Dada una imagen de forma (x, y), donde cada píxel se describe mediante una matriz (3,3). Esto se puede describir como una matriz de forma (x, y, 3,3). Además, dado un tamaño de parche de destino como (11,11), deseo extraer todos los parches superpuestos de la imagen (x, y).

    Tenga en cuenta que no quiero obtener todos los parches de la matriz x, y, 3,3, sino de la imagen x, y donde cada píxel es una matriz.

    Querré usar estos parches para un algoritmo de clasificación de parches, iterando efectivamente sobre todos los parches, extrayendo características y aprendiendo un clasificador. Sin embargo, dada una gran imagen y un gran tamaño de parche, no hay forma de realizar esta operación sin dañar la limitación de la memoria.

    Soluciones posibles:

    • sklearn.feature_extraction.image.extract_patches_2d proporciona la función de destino, pero no es aplicable porque falla debido a la limitación de la memoria. (pero funciona bien para la imagen dada con un tamaño de parche pequeño)
    • Forma rápida de dividir la imagen en parches superpuestos y combinar parches en imagen . Una gran respuesta parece liderar el camino, usando pasos y no creando una copia de la imagen de entrada. Sin embargo, no he podido adaptar la respuesta para que se ajuste a mis necesidades.

    Por lo tanto, la pregunta es: ¿Cómo puedo adaptar este código para que se ajuste a los nuevos datos de entrada?

    def patchify(img, patch_shape): img = np.ascontiguousarray(img) # won't make a copy if not needed X, Y = img.shape x, y = patch_shape shape = ((X-x+1), (Y-y+1), x, y) # number of patches, patch_shape # The right strides can be thought by: # 1) Thinking of `img` as a chunk of memory in C order # 2) Asking how many items through that chunk of memory are needed when indices # i,j,k,l are incremented by one strides = img.itemsize*np.array([Y, 1, Y, 1]) return np.lib.stride_tricks.as_strided(img, shape=shape, strides=strides) 

    Si bien la respuesta que vincula no es incorrecta, yo diría que es mejor no hacer suposiciones sobre los pasos de la matriz y simplemente reutilizar cualquier paso que ya tenga. Tiene el beneficio adicional de no requerir nunca una copia de la matriz original, incluso si no es contigua. Por su forma de imagen extendida haría:

     def patchify(img, patch_shape): X, Y, a, b = img.shape x, y = patch_shape shape = (X - x + 1, Y - y + 1, x, y, a, b) X_str, Y_str, a_str, b_str = img.strides strides = (X_str, Y_str, X_str, Y_str, a_str, b_str) return np.lib.stride_tricks.as_strided(img, shape=shape, strides=strides) 

    Es fácil dejarse llevar y desear escribir una función más general que no requiera especialización para una dimensionalidad de matriz particular. Si sientes la necesidad de ir allí, puedes encontrar algo de inspiración en esta idea .