0

I get the image numpy array from opencv, then i want to stack 32 images together, the final shape i want to obtain is (3, 32, image_height, image_width), below is the snippet of code :

import cv2
import numpy as np
video_path = 'xxxx.mp4'
frame_buffer = np.array([])
frame_index = 0
frame_buffer_num = 0
cap = cv2.VideoCapture(video_path)
while True:
  ret, image_np = cap.read()
  print(image_np.shape)
  if frame_index == 0:
    frame_buffer = image_np  # initialize empty frame_buffer
    frame_index += 1
    frame_buffer_num += 1
    continue

  frame_index += 1
  frame_buffer_num += 1
  frame_buffer = np.stack(frame_buffer, image_np)
  if frame_buffer_num == 32:
      print(frame_buffer.shape)
      break

I run it but got following error:

Traceback (most recent call last):
  File "/home/user/Python/temp.py", line 19, in <module>
    frame_buffer = np.stack(frame_buffer, image_np)
  File "<__array_function__ internals>", line 6, in stack
  File "/home/user/miniconda3/lib/python3.7/site-packages/numpy/core/shape_base.py", line 430, in stack
    axis = normalize_axis_index(axis, result_ndim)
TypeError: only size-1 arrays can be converted to Python scalars

-----------UPDATE-------------

Thanks for @abe 's inspiration, The following code works :

import cv2
import numpy as np
video_path = 'xxxx.mp4'
frame_index = 0
frame_buffer_num = 0
cap = cv2.VideoCapture(video_path)
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)  # float
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
frame_buffer = np.zeros((3, 32, int(height), int(width)))
while True:
  ret, image_np = cap.read()
  image_np = image_np.reshape(3, int(height), int(width))
  print(image_np.shape)
 
  frame_buffer[:, frame_buffer_num, :, :] = image_np
  frame_index += 1
  frame_buffer_num += 1

  if frame_buffer_num == 32:
      print(frame_buffer)
      print(frame_buffer.shape)
      break

1 Answer 1

2

The image you get for each frame has a shape (3, H, W) right? And you want to stack 32 of these. Then, you can first reshape image_np as image_np = image_np.reshape((3, 1, H, W)), then np.append(frame_buffer, image_np, axis=1) where frame_buffer was initialized with the first reshaped instance of image_np. That should result in a tensor with shape (3, 32, H, W)

Alternatively, you can initialize frame_buffer = np.zeros((3, 32, H, W)) and at each iteration, frame_buffer[:, i, :, :] = image_np

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for providing such ingenious and workable solution ! I have successfully run through it by using the alternative mthod. What I got from opencv is actually (H, W, 3), but this is not a big problem. I can add a line of code :image_np = image_np.reshape(3, H, W)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.