Je commence avec un tableau numpy d'une image.
In[1]:img = cv2.imread('test.jpg')
La forme correspond à ce à quoi vous pourriez vous attendre pour une image RVB 640x480.
In[2]:img.shape
Out[2]: (480, 640, 3)
Cependant, cette image que je possède est une image d'une vidéo de 100 images. Idéalement, j'aimerais disposer d'un seul tableau contenant toutes les données de cette vidéo, de sorte que img.shape
résultats (480, 640, 3, 100)
.
Quel est le meilleur moyen d'ajouter la trame suivante (c'est-à-dire l'ensemble de données d'image suivant, un autre tableau de 480 x 640 x 3) à mon tableau initial?
Vous demandez comment ajouter une dimension à un tableau NumPy, de sorte que cette dimension puisse ensuite être développée pour accueillir de nouvelles données. Une dimension peut être ajoutée comme suit:
image = image[..., np.newaxis]
.
Alternativement à
image = image[..., np.newaxis]
dans @ dbliss 'answer , vous pouvez également utiliser numpy.expand_dims
comme
image = np.expand_dims(image, <your desired dimension>)
Par exemple (tiré du lien ci-dessus):
x = np.array([1, 2])
print(x.shape) # prints (2,)
Ensuite
y = np.expand_dims(x, axis=0)
les rendements
array([[1, 2]])
et
y.shape
donne
(1, 2)
Vous pouvez simplement créer un tableau de la bonne taille et le remplir:
frames = np.empty((480, 640, 3, 100))
for k in xrange(nframes):
frames[:,:,:,k] = cv2.imread('frame_{}.jpg'.format(k))
si les cadres étaient des fichiers jpg individuels nommés d’une manière particulière (dans l’exemple, frame_0.jpg, frame_1.jpg, etc.).
Juste une note, vous pourriez envisager d'utiliser un (nframes, 480,640,3)
en forme de tableau, à la place.
Vous pouvez utiliser np.concatenate()
pour spécifier le axis
à ajouter, à l'aide de np.newaxis
:
import numpy as np
movie = np.concatenate((img1[:,np.newaxis], img2[:,np.newaxis]), axis=3)
Si vous lisez de nombreux fichiers:
import glob
movie = np.concatenate([cv2.imread(p)[:,np.newaxis] for p in glob.glob('*.jpg')], axis=3)
Aucune structure dans numpy ne vous permet d'ajouter plus de données ultérieurement.
Au lieu de cela, numpy place toutes vos données dans un bloc de nombres contigus (essentiellement un tableau C), et tout redimensionnement nécessite d'allouer un nouveau bloc de mémoire pour le contenir. La rapidité de Numpy est de pouvoir conserver toutes les données d’un tableau numpy dans le même bloc de mémoire; par exemple. les opérations mathématiques peuvent être parallélisées pour la vitesse et vous obtenez moins erreurs de cache .
Donc, vous aurez deux types de solutions:
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 d'étendre les dimensions des tableaux d'images individuels en premier, ni de savoir combien d'images vous attendez à l'avance.
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).
Considérez 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]]]]