2013-06-30 244 views
19

我從圖像的一個numpy數組開始。將尺寸添加到Numpy陣列

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

形狀是您對640x480 RGB圖像的預期結果。

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

但是,我擁有的這個圖像是一個100幀長的視頻幀。理想情況下,我希望有一個包含此視頻中所有數據的單個陣列,以便img.shape返回(480, 640, 3, 100)

什麼是最好的方式添加下一幀 - 也就是說,下一組圖像數據,另一個480 x 640 x 3陣列 - 我的初始數組?

回答

10

你可以只創建正確大小的前期數組並填寫:

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

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

如果幀被認爲是在某種特定的方式命名的個人JPG文件(在本例中,frame_0.jpg ,frame_1.jpg等)。

請注意,您可以考慮使用(nframes, 480,640,3)形狀的陣列。

+0

我認爲這是要走的路。如果使用串聯,則每次添加時都需要將內存中的數組移動到內存中。對於100幀應該不重要,但如果你想要去更大的視頻。順便說一句,我會用幀的數量作爲第一維度,所以有一個(100,480,640,3)數組,通過這種方式可以訪問單個幀(通常希望你會想要看什麼,對嗎?)更容易(F [1 ]而不是F [:,:,:,1])。當然,表現明智,根本就不重要。 – Magellan88

3

您可以使用np.concatenate()指定追加其axis,使用np.newaxis

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

如果你是從許多文件閱讀:

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

你詢問如何維度添加到NumPy數組,以便可以增加該維度以適應新的數據。尺寸可以如下添加:

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

+2

目前,'numpy.newaxis'被定義爲'None'(在文件'numeric.py'中),所以等價地你可以使用'image = image [...,None]。 – Ray

0

我採取了這一做法:

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

或者到

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

在@dbliss的回答,您還可以使用numpy.expand_dims

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

例如(取自以上鍊接):

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

print x.shape # prints (2,) 

然後

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

產生

array([[1, 2]]) 

y.shape 

給出

(1, 2) 
+0

如何在新維度中添加值?如果我做'y [1,0]'它會給索引超出界限的錯誤。 'y [0,1]'可以訪問 – weima

+0

@weima:不完全確定你在做什麼。你想要的輸出是什麼? – Cleb

0

numpy中沒有任何結構允許您稍後追加更多數據。

相反,numpy會將所有數據放入一個連續的數字塊(基本上是一個C數組),並且任何調整大小都需要分配一個新的內存塊來保存它。 Numpy的速度來自於能夠將所有數據保存在同一塊內存中的一個numpy數組中;例如數學運算可以是parallelized for speed,而你得到的更少,cache misses

所以,你將有兩種解決方案:

  1. 預分配的內存爲numpy的陣列並填寫值,比如在JoshAdel的答案,或
  2. 保持你的數據在一個普通的Python列表中,直到它的實際需要把它們放在一起(見下文)

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

請注意,不需要首先擴展單個圖像數組的尺寸,也不需要知道您預期會提前多少個圖像。