Ich beginne mit einer Reihe von Bildern.
In[1]:img = cv2.imread('test.jpg')
Die Form entspricht den Erwartungen eines 640 x 480 RGB-Bildes.
In[2]:img.shape
Out[2]: (480, 640, 3)
Dieses Bild, das ich habe, ist jedoch ein Bild eines Videos, das 100 Bilder lang ist. Im Idealfall hätte ich gerne ein einziges Array, das alle Daten aus diesem Video enthält, sodass sie img.shape
zurückgegeben werden (480, 640, 3, 100)
.
Was ist der beste Weg, um das nächste Bild - dh den nächsten Satz von Bilddaten, ein weiteres 480 x 640 x 3-Array - zu meinem ursprünglichen Array hinzuzufügen?
numpy.newaxis
ist definiert alsNone
(in Dateinumeric.py
), so dass Sie äquivalent `image = image [..., None] verwenden können.None
. Verwenden Sie,np.newaxis
weil explizit besser als implizit ist.None
bedeutet nichts. Es ist explizit. Es istNone
. Klar ausgedrückt.None
ist eine Sache in Python. Es gibt keinen Zweifel.None
ist das letzte Detail, man kann nicht tiefer gehen. Auf der anderen Seitenumpy.newaxis
impliziertNone
. Es ist im WesentlichenNone
. Es istNone
. Ist aberNone
implizit. Es wirdNone
jedoch nicht direkt als ausgedrücktNone
. Explizit klar und detailliert ausgedrückt, ohne Raum für Verwirrung oder Zweifel. Implizit vorgeschlagen, aber nicht direkt ausgedrückt. Ich muss hinzufügen, dass es aus API-Sicht sicherer ist, es zu verwendennumpy.newaxis
.Alternativ zu
In der Antwort von @dbliss können Sie auch
numpy.expand_dims
like verwendenZum Beispiel (aus dem obigen Link):
x = np.array([1, 2]) print(x.shape) # prints (2,)
Dann
y = np.expand_dims(x, axis=0)
ergibt
array([[1, 2]])
und
gibt
(1, 2)
quelle
y[1,0]
, gibt es Index außerhalb der Grenzen Fehler.y[0,1]
ist zugänglichSie können einfach ein Array mit der richtigen Größe im Voraus erstellen und es füllen:
frames = np.empty((480, 640, 3, 100)) for k in xrange(nframes): frames[:,:,:,k] = cv2.imread('frame_{}.jpg'.format(k))
Wenn es sich bei den Frames um einzelne JPG-Dateien handelt, die auf eine bestimmte Weise benannt wurden (im Beispiel frame_0.jpg, frame_1.jpg usw.).
Nur eine Anmerkung, Sie könnten stattdessen ein
(nframes, 480,640,3)
geformtes Array verwenden.quelle
Pythonic
X = X[:, :, None]
das ist äquivalent zu
X = X[:, :, numpy.newaxis]
undX = numpy.expand_dims(X, axis=-1)
Da Sie jedoch explizit nach dem Stapeln von Bildern fragen, würde ich empfehlen, die
list
Bilder zu stapeln, dienp.stack([X1, X2, X3])
Sie möglicherweise in einer Schleife gesammelt haben.Wenn Ihnen die Reihenfolge der Abmessungen nicht gefällt, können Sie sie neu anordnen
np.transpose()
quelle
Sie können
np.concatenate()
angeben, welcheaxis
angehängt werden sollen, indem Sie Folgendes verwendennp.newaxis
:import numpy as np movie = np.concatenate((img1[:,np.newaxis], img2[:,np.newaxis]), axis=3)
Wenn Sie aus vielen Dateien lesen:
import glob movie = np.concatenate([cv2.imread(p)[:,np.newaxis] for p in glob.glob('*.jpg')], axis=3)
quelle
In numpy gibt es keine Struktur, mit der Sie später weitere Daten anhängen können.
Stattdessen fügt numpy alle Ihre Daten in einen zusammenhängenden Teil von Zahlen ein (im Grunde genommen ein C-Array), und für jede Größenänderung muss ein neuer Teil des Speichers zugewiesen werden, um sie zu speichern. Die Geschwindigkeit von Numpy beruht darauf, dass alle Daten in einem numpy-Array im selben Speicherbereich gespeichert werden können. Beispielsweise können mathematische Operationen aus Geschwindigkeitsgründen parallelisiert werden und Sie erhalten weniger Cache-Fehler .
Sie haben also zwei Arten von Lösungen:
images = [] for i in range(100): new_image = # pull image from somewhere images.append(new_image) images = np.stack(images, axis=3)
Beachten Sie, dass Sie weder die Abmessungen der einzelnen Bildarrays zuerst erweitern noch wissen müssen, wie viele Bilder Sie im Voraus erwarten.
quelle
Betrachten Sie Ansatz 1 mit der Umformmethode und Ansatz 2 mit der Methode np.newaxis, die das gleiche Ergebnis erzielen:
#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)
Wir haben als Ergebnis:
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]]]]
quelle
Ich folgte diesem Ansatz:
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).
quelle