2013-06-30 25 views
19

Ich beginne mit einem numply Array eines Bildes.Hinzufügen von Dimensionen zu einem Numpy Array

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

Die Form ist, was Sie für ein 640x480 RGB-Bild erwarten könnte.

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

Doch dieses Bild, das ich habe, ist ein Rahmen aus einem Video, das 100 Frames lang. Idealerweise hätte ich gerne ein einzelnes Array, das alle Daten dieses Videos enthält, so dass img.shape(480, 640, 3, 100) zurückgibt.

Was ist der beste Weg, um den nächsten Frame, das heißt, die nächste Reihe von Bilddaten, ein weiteres 480 x 640 x 3-Array zu meinem ursprünglichen Array hinzuzufügen?

Antwort

10

Sie könnten nur ein Array mit der richtigen Größe up-front und füllen Sie es schaffen:

frames = np.empty((480, 640, 3, 100)) 

for k in xrange(nframes): 
    frames[:,:,:,k] = cv2.imread('frame_{}.jpg'.format(k)) 

wenn der Rahmen einzelnen JPG-Datei war, die (im Beispiel frame_0.jpg in einer bestimmten Art und Weise benannt wurden , frame_1.jpg, usw.).

Nur eine Anmerkung, Sie könnten stattdessen ein (nframes, 480,640,3) geformtes Array in Betracht ziehen.

+0

Ich denke, das ist der Weg zu gehen. Wenn Sie die Verkettung verwenden, müssen Sie das Array jedes Mal in den Speicher verschieben, wenn Sie es hinzufügen. Für 100 Frames sollte das eigentlich egal sein, aber wenn man zu größeren Videos gehen möchte. BTW, ich hätte die Anzahl der Frames als erste Dimension verwendet, also ein (100,480,640,3) Array, so dass Sie auf einzelne Frames zugreifen können (was Sie normalerweise sehen wollen, oder?) Einfacher (F [1 ] anstelle von F [:,:,:, 1]). Natürlich sollte es in Bezug auf die Leistung keine Rolle spielen. – Magellan88

3

Sie np.concatenate() Spezifizierungs verwenden können, die axis anhängen, mit np.newaxis:

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

Wenn Sie viele Dateien zu lesen:

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

Sie fragen, wie Sie eine Dimension ein hinzufügen NumPy-Array, sodass diese Dimension dann vergrößert werden kann, um neue Daten aufzunehmen. Eine Dimension kann wie folgt hinzugefügt werden:

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

+2

Momentan ist 'numpy.newaxis' definiert als 'None' (in der Datei' numeric.py'), also können Sie auch 'image = image [..., None] verwenden. – Ray

0

ich diesen 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). 
3

Alternativ zu

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

in @dbliss, können Sie auch von der numpy.expand_dims wie

image = np.expand_dims(image, <your desired dimension>) 

Zum Beispiel (entnommen verwenden Link oben):

x = np.array([1, 2]) 

print x.shape # prints (2,) 

Dann

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

ergibt

array([[1, 2]]) 

und

y.shape 

gibt

(1, 2) 
+0

Wie füge ich Werte in die neue Dimension ein? Wenn ich 'y [1,0]' mache, ergibt dies einen Index außerhalb des zulässigen Bereichs. 'y [0,1]' ist zugänglich – weima

+0

@weima: Nicht ganz sicher, was Sie suchen. Was ist Ihre gewünschte Ausgabe? – Cleb

0

In numpy gibt es keine Struktur, mit der Sie später weitere Daten anhängen können.

Stattdessen setzt numpy alle Ihre Daten in einen zusammenhängenden Teil der Zahlen (im Grunde; ein C-Array), und jede Größenänderung erfordert ein neues Stück Speicher zuzuordnen, um es zu halten. Die Geschwindigkeit von Numpy ergibt sich daraus, dass alle Daten in einem Array mit mehreren Nummern im gleichen Speicherbereich gespeichert werden können. z.B. mathematische Operationen können parallelized for speed sein und Sie erhalten weniger cache misses.

Sie werden also zwei Arten von Lösungen:

  1. vorbelegen den Speicher für die numpy Array und in den Werten, wie in JoshAdel Antwort füllen, oder
  2. Halten Sie Ihre Daten in einem normalen Python Liste, bis es tatsächlich gebraucht wird, sie alle zusammen (siehe unten)

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

zu setzen

Beachten Sie, dass die Dimensionen der einzelnen Bildfelder nicht zuerst erweitert werden müssen und Sie nicht wissen müssen, wie viele Bilder Sie im Voraus erwarten.

Verwandte Themen