Ответ 1
Вы спрашиваете, как добавить измерение в массив NumPy, чтобы затем это измерение можно было увеличить для размещения новых данных. Размер можно добавить следующим образом:
image = image[..., np.newaxis]
Я начинаю с массива numpy изображения.
In[1]:img = cv2.imread('test.jpg')
Форма - это то, что вы можете ожидать для изображения RGB 640x480.
In[2]:img.shape
Out[2]: (480, 640, 3)
Однако это изображение, которое у меня есть, представляет собой кадр видео, который составляет 100 кадров в длину. В идеале я хотел бы иметь один массив, содержащий все данные этого видео, так что img.shape
возвращает (480, 640, 3, 100)
.
Каков наилучший способ добавить в мой начальный массив следующий кадр, то есть следующий набор данных изображения, еще один массив 480 x 640 x 3?
Вы спрашиваете, как добавить измерение в массив NumPy, чтобы затем это измерение можно было увеличить для размещения новых данных. Размер можно добавить следующим образом:
image = image[..., np.newaxis]
В качестве альтернативы
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)
Вы можете просто создать массив правильного размера вверх и заполнить его:
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)
.
Вы можете использовать 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)
В numpy нет структуры, которая позволяет добавлять дополнительные данные позже.
Вместо этого numpy помещает все ваши данные в смежный фрагмент чисел (в основном, массив C), и для любого изменения размера требуется выделение нового фрагмента памяти для его хранения. Скорость работы с памятью зависит от возможности хранить все данные в массиве numpy в одном блоке памяти; например математические операции могут распараллеливаться для скорости, и вы получите меньше пропуски кеша.
Итак, у вас будет два вида решений:
images = []
for i in range(100):
new_image = # pull image from somewhere
images.append(new_image)
images = np.stack(images, axis=3)
Обратите внимание, что нет необходимости сначала расширять размеры отдельных массивов изображений, и вам не нужно знать, сколько изображений вы ожидаете раньше времени.
Я придерживался такого подхода:
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).
Рассмотрим подход 1 с методом изменения формы и подход 2 с методом np.newaxis, которые дают тот же результат:
#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]]]]