Estou começando com uma matriz numpy de uma imagem.
In[1]:img = cv2.imread('test.jpg')
O formato é o que você espera de uma imagem RGB de 640x480.
In[2]:img.shape
Out[2]: (480, 640, 3)
No entanto, esta imagem que tenho é um quadro de um vídeo, que tem 100 quadros de comprimento. Idealmente, gostaria de ter uma única matriz que contenha todos os dados deste vídeo de forma que img.shape
retorne (480, 640, 3, 100)
.
Qual é a melhor maneira de adicionar o próximo quadro - isto é, o próximo conjunto de dados de imagem, outro array 480 x 640 x 3 - ao meu array inicial?
numpy.newaxis
está definido para estarNone
(no arquivonumeric.py
), então de forma equivalente você pode usar `image = image [..., None].None
. Usenp.newaxis
porque explícito é melhor do que implícito.None
não implica nada. É explícito. ÉNone
. Declarado claramente.None
é uma coisa em python. Não há duvidas.None
é o último detalhe, você não pode ir mais fundo. Por outro lado,numpy.newaxis
implicaNone
. É, essencialmenteNone
,. ÉNone
. Mas estáNone
implicitamente. ÉNone
embora não expressa diretamente comoNone
. Explicito declarado de forma clara e detalhada, não deixando espaço para confusão ou dúvida. Sugestão implícita, embora não expressa diretamente. Devo acrescentar que, do ponto de vista da API, é mais seguro de usarnumpy.newaxis
.Alternativamente para
na resposta de @dbliss , você também pode usar
numpy.expand_dims
comoPor exemplo (retirado do link acima):
x = np.array([1, 2]) print(x.shape) # prints (2,)
Então
y = np.expand_dims(x, axis=0)
rendimentos
array([[1, 2]])
e
dá
(1, 2)
fonte
y[1,0]
isso, o índice está fora dos limites do erro.y[0,1]
está acessívelVocê pode simplesmente criar uma matriz do tamanho correto antecipadamente e preenchê-la:
frames = np.empty((480, 640, 3, 100)) for k in xrange(nframes): frames[:,:,:,k] = cv2.imread('frame_{}.jpg'.format(k))
se os quadros forem arquivos jpg individuais nomeados de alguma forma particular (no exemplo, frame_0.jpg, frame_1.jpg, etc).
Apenas uma nota, você pode considerar o uso de uma
(nframes, 480,640,3)
matriz em forma.fonte
Pitônico
X = X[:, :, None]
que é equivalente a
X = X[:, :, numpy.newaxis]
eX = numpy.expand_dims(X, axis=-1)
Mas como você está perguntando explicitamente sobre o empilhamento de imagens, recomendo empilhar as
list
imagensnp.stack([X1, X2, X3])
que você possa ter coletado em um loop.Se você não gosta da ordem das dimensões, você pode reorganizar com
np.transpose()
fonte
Você pode usar
np.concatenate()
especificando qualaxis
anexar, usandonp.newaxis
:import numpy as np movie = np.concatenate((img1[:,np.newaxis], img2[:,np.newaxis]), axis=3)
Se você estiver lendo muitos arquivos:
import glob movie = np.concatenate([cv2.imread(p)[:,np.newaxis] for p in glob.glob('*.jpg')], axis=3)
fonte
Não existe uma estrutura em numpy que permita anexar mais dados posteriormente.
Em vez disso, numpy coloca todos os seus dados em um bloco contíguo de números (basicamente; uma matriz C), e qualquer redimensionamento requer a alocação de um novo bloco de memória para mantê-lo. A velocidade do Numpy vem de ser capaz de manter todos os dados em um array numpy no mesmo pedaço de memória; por exemplo, as operações matemáticas podem ser paralelizadas para velocidade e você obtém menos perdas de cache .
Portanto, você terá dois tipos de soluções:
images = [] for i in range(100): new_image = # pull image from somewhere images.append(new_image) images = np.stack(images, axis=3)
Observe que não há necessidade de expandir as dimensões das matrizes de imagens individuais primeiro, nem você precisa saber quantas imagens você espera com antecedência.
fonte
Considere a abordagem 1 com o método de reformulação e a abordagem 2 com o método np.newaxis que produzem o mesmo resultado:
#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)
Temos como resultado:
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]]]]
fonte
Eu segui esta abordagem:
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).
fonte