Añadir dimensiones a una matriz Numpy

Estoy empezando con una matriz numpy de una imagen.

In[1]:img = cv2.imread('test.jpg') 

La forma es lo que se puede esperar de una imagen RGB de 640×480.

 In[2]:img.shape Out[2]: (480, 640, 3) 

Sin embargo, esta imagen que tengo es un cuadro de un video, que tiene 100 cuadros de largo. Idealmente, me gustaría tener una única matriz que contenga todos los datos de este video, de manera que img.shape devuelva (480, 640, 3, 100) .

¿Cuál es la mejor manera de agregar el siguiente fotogtwig, es decir, el siguiente conjunto de datos de imagen, otra matriz de 480 x 640 x 3, a mi matriz inicial?

Está preguntando cómo agregar una dimensión a una matriz NumPy, de modo que esa dimensión pueda crecer para adaptarse a nuevos datos. Una dimensión se puede agregar de la siguiente manera:

image = image[..., np.newaxis] .

Alternativamente a

 image = image[..., np.newaxis] 

En la respuesta de @dbliss , también puedes usar numpy.expand_dims como

 image = np.expand_dims(image, ) 

Por ejemplo (tomado del enlace de arriba):

 x = np.array([1, 2]) print(x.shape) # prints (2,) 

Entonces

 y = np.expand_dims(x, axis=0) 

rendimientos

 array([[1, 2]]) 

y

 y.shape 

da

 (1, 2) 

Simplemente puede crear una matriz del tamaño correcto por adelantado y rellenarla:

 frames = np.empty((480, 640, 3, 100)) for k in xrange(nframes): frames[:,:,:,k] = cv2.imread('frame_{}.jpg'.format(k)) 

si los marcos eran archivos jpg individuales que fueron nombrados de alguna manera en particular (en el ejemplo, frame_0.jpg, frame_1.jpg, etc.).

Solo una nota, puede considerar usar una (nframes, 480,640,3) con forma (nframes, 480,640,3) , en su lugar.

Puede usar np.concatenate() especificando a qué axis anexar, usando np.newaxis :

 import numpy as np movie = np.concatenate((img1[:,np.newaxis], img2[:,np.newaxis]), axis=3) 

Si estás leyendo de muchos archivos:

 import glob movie = np.concatenate([cv2.imread(p)[:,np.newaxis] for p in glob.glob('*.jpg')], axis=3) 

No hay ninguna estructura en el número que le permita agregar más datos más adelante.

En su lugar, numpy coloca todos sus datos en una parte contigua de números (básicamente, una matriz de C), y cualquier cambio de tamaño requiere asignar una nueva parte de memoria para retenerla. La velocidad de Numpy viene de poder mantener todos los datos en una matriz numpy en la misma porción de memoria; Por ejemplo, las operaciones matemáticas se pueden paralelizar para la velocidad y se obtienen menos errores de caché .

Así tendrás dos tipos de soluciones:

  1. Asigne previamente la memoria para la matriz numpy y complete los valores, como en la respuesta de JoshAdel, o
  2. Mantenga sus datos en una lista de python normal hasta que realmente se necesiten para juntarlos todos (ver más abajo)

 images = [] for i in range(100): new_image = # pull image from somewhere images.append(new_image) images = np.stack(images, axis=3) 

Tenga en cuenta que no es necesario ampliar primero las dimensiones de las matrices de imágenes individuales, ni tampoco saber cuántas imágenes espera antes de tiempo.

Seguí este enfoque:

 import numpy as np import cv2 ls = [] for image in image_paths: ls.append(cv2.imread('test.jpg')) img_np = np.array(ls) # shape (100, 480, 640, 3) img_np = np.rollaxis(img_np, 0, 4) # shape (480, 640, 3, 100).