I'm starting off with a numpy array of an image.
我开始使用numpy数组图像。
In[1]:img = cv2.imread('test.jpg')
The shape is what you might expect for a 640x480 RGB image.
形状是您对640x480 RGB图像的期望。
In[2]:img.shape
Out[2]: (480, 640, 3)
However, this image that I have is a frame of a video, which is 100 frames long. Ideally, I would like to have a single array that contains all the data from this video such that img.shape
returns (480, 640, 3, 100)
.
但是,我拥有的这个图像是一个100帧长的视频帧。理想情况下,我希望有一个包含此视频中所有数据的数组,以便img.shape返回(480,640,3,100)。
What is the best way to add the next frame -- that is, the next set of image data, another 480 x 640 x 3 array -- to my initial array?
将下一帧(即下一组图像数据,另一个480 x 640 x 3阵列)添加到我的初始阵列的最佳方法是什么?
6 个解决方案
#1
29
You're asking how to add a dimension to a NumPy array, so that that dimension can then be grown to accommodate new data. A dimension can be added as follows:
您正在询问如何向NumPy数组添加维度,以便可以增大该维度以适应新数据。可以按如下方式添加维度:
image = image[..., np.newaxis]
.
image = image [...,np.newaxis]。
#2
12
You could just create an array of the correct size up-front and fill it:
您可以在前面创建一个正确大小的数组并填充它:
frames = np.empty((480, 640, 3, 100))
for k in xrange(nframes):
frames[:,:,:,k] = cv2.imread('frame_{}.jpg'.format(k))
if the frames were individual jpg file that were named in some particular way (in the example, frame_0.jpg, frame_1.jpg, etc).
如果帧是以某种特定方式命名的单个jpg文件(在示例中为frame_0.jpg,frame_1.jpg等)。
Just a note, you might consider using a (nframes, 480,640,3)
shaped array, instead.
只需注意,您可以考虑使用(nframes,480,640,3)形状的阵列。
#3
8
Alternatively to
或者替代
image = image[..., np.newaxis]
in @dbliss' answer, you can also use numpy.expand_dims
like
在@dbliss的回答中,你也可以使用numpy.expand_dims之类的
image = np.expand_dims(image, <your desired dimension>)
For example (taken from the link above):
例如(取自上面的链接):
x = np.array([1, 2])
print(x.shape) # prints (2,)
Then
然后
y = np.expand_dims(x, axis=0)
yields
产量
array([[1, 2]])
and
和
y.shape
gives
给
(1, 2)
#4
4
You can use np.concatenate()
specifying which axis
to append, using np.newaxis
:
您可以使用np.concatenate()使用np.newaxis指定要追加的轴:
import numpy as np
movie = np.concatenate((img1[:,np.newaxis], img2[:,np.newaxis]), axis=3)
If you are reading from many files:
如果您正在阅读许多文件:
import glob
movie = np.concatenate([cv2.imread(p)[:,np.newaxis] for p in glob.glob('*.jpg')], axis=3)
#5
1
I followed this approach:
我遵循这种方法:
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).
#6
1
There is no structure in numpy that allows you to append more data later.
numpy中没有允许您稍后添加更多数据的结构。
Instead, numpy puts all of your data into a contiguous chunk of numbers (basically; a C array), and any resize requires allocating a new chunk of memory to hold it. Numpy's speed comes from being able to keep all the data in a numpy array in the same chunk of memory; e.g. mathematical operations can be parallelized for speed and you get less cache misses.
相反,numpy将所有数据放入一个连续的数字块(基本上是一个C数组),任何调整大小都需要分配一大块内存来保存它。 Numpy的速度来自于能够将所有数据保存在同一块内存中的numpy数组中;例如数学运算可以并行化以提高速度,减少缓存未命中率。
So you will have two kinds of solutions:
所以你将有两种解决方案:
- Pre-allocate the memory for the numpy array and fill in the values, like in JoshAdel's answer, or
- 为numpy数组预先分配内存并填写值,如JoshAdel的答案,或者
- Keep your data in a normal python list until it's actually needed to put them all together (see below)
- 将数据保存在普通的python列表中,直到实际需要将它们放在一起(见下文)
images = []
for i in range(100):
new_image = # pull image from somewhere
images.append(new_image)
images = np.stack(images, axis=3)
Note that there is no need to expand the dimensions of the individual image arrays first, nor do you need to know how many images you expect ahead of time.
请注意,不需要首先扩展单个图像阵列的尺寸,也不需要知道您预期的图像数量。
#1
29
You're asking how to add a dimension to a NumPy array, so that that dimension can then be grown to accommodate new data. A dimension can be added as follows:
您正在询问如何向NumPy数组添加维度,以便可以增大该维度以适应新数据。可以按如下方式添加维度:
image = image[..., np.newaxis]
.
image = image [...,np.newaxis]。
#2
12
You could just create an array of the correct size up-front and fill it:
您可以在前面创建一个正确大小的数组并填充它:
frames = np.empty((480, 640, 3, 100))
for k in xrange(nframes):
frames[:,:,:,k] = cv2.imread('frame_{}.jpg'.format(k))
if the frames were individual jpg file that were named in some particular way (in the example, frame_0.jpg, frame_1.jpg, etc).
如果帧是以某种特定方式命名的单个jpg文件(在示例中为frame_0.jpg,frame_1.jpg等)。
Just a note, you might consider using a (nframes, 480,640,3)
shaped array, instead.
只需注意,您可以考虑使用(nframes,480,640,3)形状的阵列。
#3
8
Alternatively to
或者替代
image = image[..., np.newaxis]
in @dbliss' answer, you can also use numpy.expand_dims
like
在@dbliss的回答中,你也可以使用numpy.expand_dims之类的
image = np.expand_dims(image, <your desired dimension>)
For example (taken from the link above):
例如(取自上面的链接):
x = np.array([1, 2])
print(x.shape) # prints (2,)
Then
然后
y = np.expand_dims(x, axis=0)
yields
产量
array([[1, 2]])
and
和
y.shape
gives
给
(1, 2)
#4
4
You can use np.concatenate()
specifying which axis
to append, using np.newaxis
:
您可以使用np.concatenate()使用np.newaxis指定要追加的轴:
import numpy as np
movie = np.concatenate((img1[:,np.newaxis], img2[:,np.newaxis]), axis=3)
If you are reading from many files:
如果您正在阅读许多文件:
import glob
movie = np.concatenate([cv2.imread(p)[:,np.newaxis] for p in glob.glob('*.jpg')], axis=3)
#5
1
I followed this approach:
我遵循这种方法:
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).
#6
1
There is no structure in numpy that allows you to append more data later.
numpy中没有允许您稍后添加更多数据的结构。
Instead, numpy puts all of your data into a contiguous chunk of numbers (basically; a C array), and any resize requires allocating a new chunk of memory to hold it. Numpy's speed comes from being able to keep all the data in a numpy array in the same chunk of memory; e.g. mathematical operations can be parallelized for speed and you get less cache misses.
相反,numpy将所有数据放入一个连续的数字块(基本上是一个C数组),任何调整大小都需要分配一大块内存来保存它。 Numpy的速度来自于能够将所有数据保存在同一块内存中的numpy数组中;例如数学运算可以并行化以提高速度,减少缓存未命中率。
So you will have two kinds of solutions:
所以你将有两种解决方案:
- Pre-allocate the memory for the numpy array and fill in the values, like in JoshAdel's answer, or
- 为numpy数组预先分配内存并填写值,如JoshAdel的答案,或者
- Keep your data in a normal python list until it's actually needed to put them all together (see below)
- 将数据保存在普通的python列表中,直到实际需要将它们放在一起(见下文)
images = []
for i in range(100):
new_image = # pull image from somewhere
images.append(new_image)
images = np.stack(images, axis=3)
Note that there is no need to expand the dimensions of the individual image arrays first, nor do you need to know how many images you expect ahead of time.
请注意,不需要首先扩展单个图像阵列的尺寸,也不需要知道您预期的图像数量。