将维度添加到Numpy数组

时间:2013-06-30 21:10:56

标签: python arrays opencv 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阵列)添加到我的初始数组的最佳方法是什么?

9 个答案:

答案 0 :(得分:41)

您正在询问如何向NumPy数组添加维度,以便可以增大该维度以容纳新数据。可以按如下方式添加维度:

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

答案 1 :(得分:26)

的替代方案
image = image[..., np.newaxis]
@dbliss' answer

,您也可以使用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)

答案 2 :(得分:18)

您可以在前面创建一个正确大小的数组并填充它:

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)形状的数组。

答案 3 :(得分:7)

Pythonic

X = X[:, :, None]

等效于

X = X[:, :, numpy.newaxis]X = numpy.expand_dims(X, axis=-1)

但是当您明确询问有关堆叠图像时, 我建议您将list的{​​{1}}图像np.stack([X1, X2, X3])堆积成一个循环。

如果您不喜欢尺寸的顺序,则可以使用np.transpose()

重新排列

答案 4 :(得分:5)

您可以使用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)

如果您正在阅读许多文件:

{{1}}

答案 5 :(得分:2)

numpy中没有允许您稍后添加更多数据的结构。

相反,numpy将所有数据放入一个连续的数字块(基本上是一个C数组),任何调整大小都需要分配一大块内存来保存它。 Numpy的速度来自于能够将所有数据保存在同一块内存中的numpy数组中;例如数学运算可以是parallelized for speed,你可以减少cache misses

所以你将有两种解决方案:

  1. 为numpy数组预先分配内存并填写值,如JoshAdel的答案,或
  2. 将您的数据保存在普通的python列表中,直到实际需要将它们放在一起(见下文)
  3. images = []
    for i in range(100):
        new_image = # pull image from somewhere
        images.append(new_image)
    images = np.stack(images, axis=3)
    

    请注意,不需要首先扩展单个图像阵列的尺寸,也不需要知道您预期会有多少图像。

答案 6 :(得分:1)

我遵循了这种方法:

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

答案 7 :(得分:0)

考虑使用重整方法的方法1和使用np.newaxis方法的方法2会产生相同的结果:

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

作为结果:

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]]]]

答案 8 :(得分:0)

这对我有用:

image = image[..., None]