web-dev-qa-db-ja.com

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配列を最初の配列に追加する最良の方法は何ですか?

45
Chris

NumPy配列にディメンションを追加して、そのディメンションを新しいデータに合わせて拡大できるようにする方法を求めています。ディメンションは次のように追加できます。

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

47
dbliss

代わりに

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)
31
Cleb

正しいサイズの配列を事前に作成して入力するだけで済みます。

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)形の配列を使用することを検討してください。

19
JoshAdel

np.concatenate()を使用して、np.newaxisを使用して、追加するaxisを指定できます。

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

Numpyには、後でさらにデータを追加できる構造はありません。

代わりに、numpyはすべてのデータを連続した数字のチャンク(基本的にはC配列)に入れます。サイズを変更するには、それを保持するために新しいメモリーのチャンクを割り当てる必要があります。 Numpyの速度は、numpy配列内のすべてのデータを同じメモリチャンクに保持できることにあります。例えば数学的操作は 速度のために並列化された であり、より少ない キャッシュミス になります。

したがって、2種類のソリューションがあります。

  1. JoshAdelの答えのように、numpy配列にメモリを事前に割り当て、値を入力します。または
  2. データをすべてまとめるのに実際に必要になるまで、データを通常のpythonリストに保持します(以下を参照)

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

最初に個々の画像配列の次元を拡張する必要はなく、事前に何枚の画像を予想するかを知る必要もないことに注意してください。

2
Multihunter

私はこのアプローチに従いました:

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
richar8086

同じ結果を生成する、reshapeメソッドを使用したアプローチ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]]]]
0
Roman