178 votes

Comment ajouter de nouvelles dimensions à un tableau Numpy ?

Je commence avec un tableau numpy d'une image.

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

La forme est celle à laquelle on peut s'attendre pour une image RVB de 640x480.

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

Cependant, l'image que je possède est une image d'une vidéo de 100 images. Idéalement, j'aimerais avoir un tableau unique qui contienne toutes les données de cette vidéo, de telle sorte que img.shape renvoie à (480, 640, 3, 100) .

Quelle est la meilleure façon d'ajouter l'image suivante - c'est-à-dire le prochain ensemble de données d'image, un autre tableau 480 x 640 x 3 - à mon tableau initial ?

3voto

Roman Points 1983

Considérons l'approche 1 avec la méthode reshape et l'approche 2 avec la méthode np.newaxis qui produisent le même résultat :

#Lets suppose, we have:
x = [1,2,3,4,5,6,7,8,9]
print('I. x',x)

xNpArr = np.array(x)
print('II. xNpArr',xNpArr)
print('III. xNpArr', xNpArr.shape)

xNpArr_3x3 = xNpArr.reshape((3,3))
print('IV. xNpArr_3x3.shape', xNpArr_3x3.shape)
print('V. xNpArr_3x3', xNpArr_3x3)

#Approach 1 with reshape method
xNpArrRs_1x3x3x1 = xNpArr_3x3.reshape((1,3,3,1))
print('VI. xNpArrRs_1x3x3x1.shape', xNpArrRs_1x3x3x1.shape)
print('VII. xNpArrRs_1x3x3x1', xNpArrRs_1x3x3x1)

#Approach 2 with np.newaxis method
xNpArrNa_1x3x3x1 = xNpArr_3x3[np.newaxis, ..., np.newaxis]
print('VIII. xNpArrNa_1x3x3x1.shape', xNpArrNa_1x3x3x1.shape)
print('IX. xNpArrNa_1x3x3x1', xNpArrNa_1x3x3x1)

Nous avons comme résultat :

I. x [1, 2, 3, 4, 5, 6, 7, 8, 9]

II. xNpArr [1 2 3 4 5 6 7 8 9]

III. xNpArr (9,)

IV. xNpArr_3x3.shape (3, 3)

V. xNpArr_3x3 [[1 2 3]
 [4 5 6]
 [7 8 9]]

VI. xNpArrRs_1x3x3x1.shape (1, 3, 3, 1)

VII. xNpArrRs_1x3x3x1 [[[[1]
   [2]
   [3]]

  [[4]
   [5]
   [6]]

  [[7]
   [8]
   [9]]]]

VIII. xNpArrNa_1x3x3x1.shape (1, 3, 3, 1)

IX. xNpArrNa_1x3x3x1 [[[[1]
   [2]
   [3]]

  [[4]
   [5]
   [6]]

  [[7]
   [8]
   [9]]]]

2voto

Multihunter Points 1292

Il n'y a pas de structure dans numpy qui vous permette d'ajouter plus de données plus tard.

Au lieu de cela, numpy place toutes vos données dans un bloc de nombres contigus (en gros, un tableau C), et toute redimensionnement nécessite l'allocation d'un nouveau bloc de mémoire pour le contenir. La rapidité de Numpy vient du fait qu'il est possible de garder toutes les données d'un tableau numpy dans le même morceau de mémoire ; par exemple, les opérations mathématiques peuvent être parallélisé pour la vitesse et vous obtenez moins manques dans le cache .

Vous aurez donc deux types de solutions :

  1. Pré-allouer la mémoire pour le tableau numpy et remplir les valeurs, comme dans la réponse de JoshAdel, ou bien
  2. Conservez vos données dans une liste python normale jusqu'à ce qu'il soit nécessaire de les assembler (voir ci-dessous).

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

Notez qu'il n'est pas nécessaire de développer d'abord les dimensions des tableaux d'images individuels, ni de savoir à l'avance combien d'images vous attendez.

2voto

user48956 Points 1708

Vous pouvez utiliser la pile avec le paramètre d'axe :

img.shape  # h,w,3
imgs = np.stack([img1,img2,img3,img4], axis=-1)   # -1 = new axis is last
imgs.shape #  h,w,3,nimages

Par exemple : pour convertir les niveaux de gris en couleurs :

>>> d = np.zeros((5,4), dtype=int)  # 5x4
>>> d[2,3] = 1

>>> d3.shape
Out[30]: (5, 4, 3)

>>> d3 = np.stack([d,d,d], axis=-2)  # 5x4x3   -1=as last axis
>>> d3[2,3]
Out[32]: array([1, 1, 1])

1voto

richar8086 Points 140

J'ai suivi cette approche :

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).

1voto

Sherzod Points 82

Cela a marché pour moi :

image = image[..., None]

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X