[python] Numpy 배열에 새 차원을 추가하려면 어떻게해야합니까?

나는 이미지의 numpy 배열로 시작합니다.

In[1]:img = cv2.imread('test.jpg')

모양은 640×480 RGB 이미지에 대해 예상 할 수있는 것입니다.

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), 대신 모양 배열을 사용하는 것을 고려할 수 있습니다 .


답변

Pythonic

X = X[:, :, None]

이는

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

그러나 이미지 스택에 대해 명시 적으로 질문 하고 있으므로 루프에서 수집 한 list이미지 를 스택하는 것이 좋습니다 np.stack([X1, X2, X3]).

치수 순서가 마음에 들지 않으면 재정렬 할 수 있습니다. np.transpose()


답변

다음을 사용 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의 속도는 동일한 메모리 청크에있는 numpy 배열의 모든 데이터를 유지할 수 있다는 점에서 비롯됩니다. 예를 들어 수학적 연산은 속도 를 위해 병렬화 될 수 있으며 캐시 미스 가 줄어 듭니다 .

따라서 두 가지 종류의 솔루션이 있습니다.

  1. numpy 배열에 대한 메모리를 미리 할당하고 JoshAdel의 답변과 같이 값을 입력하거나
  2. 데이터를 실제로 모두 합쳐야 할 때까지 일반 파이썬 목록에 보관하십시오 (아래 참조).

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

먼저 개별 이미지 배열의 차원을 확장 할 필요가 없으며 예상되는 이미지 수를 미리 알 필요도 없습니다.


답변

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