将 Numpy 数组列表到单个 Numpy 数组而不复制数据



我正在使用Python OpenCV读取视频数据,并希望存储K帧数。目前,我有执行以下操作(伪代码)的循环:

frame_list = 1:K
frame_buffer = list(map(ReadFrameNumber, frame_list))

我现在有一个列表,frame_buffer,长度为 K 帧,数据是 NxMx3 numpy 数组。这一切都很好,但是现在我想重组数据,以便我可以有效地使用scikit-learn来尝试一些模型。为了做到这一点,我需要创建一个 numpy 数组,它可以结构化为 ((N*M*3) x (K)) 或 ((K) x (N*M*3) 矩阵。我可以成功地做到这一点,但是数据正在复制,这使得此功能非常慢。我正在使用numpy.ravelnumpy.asarraynumpy.transpose的组合来完成我的慢速方法。我基本上只是想要一个新的数据视图。

这是我现在正在做的事情,这不起作用(需要太长时间):

def RearrangeData(data): 
   b = list(map(np.ravel, data))
   b = np.asarray(b, dtype=np.float32)
   return b

更新:这就是我从opencv读取帧的方式:

import numpy as np
import cv2 
K= 10
num_frames = K
cap = cv2.VideoCapture(filename)
    def PopulateBuffer(num):
        cap.set(cv2.CAP_PROP_POS_FRAMES, num)
        ret, frame = cap.read()
        if not ret:
            print("Fatal Error: Could not read/decode frame %d" % num)
            exit(-1)
        return frame
frame_nums = list(range(0, int(num_frames)))
return (list(map(PopulateBuffer, frame_nums)))

所以我相信我想通了。

  • 第一个错误:使用列表在帧中复制。我最终预分配了一个 numpy 数组:

     #Preallocate frame buffer                              
     frame_buffer = np.zeros((num_frames,) + frame.shape)
     # Copy frames
     for i in range(0, num_frames):                    
         frame_buffer[i, :, :, :] = PopulateBuffer(i)
    
  • 第二个错误:我没有意识到numpy.reshape()会创建一个新视图(在大多数情况下我认为)。因此,一旦我正确设置了初始阵列,就只需执行以下操作即可。

    buf_s = frame_buffer.shape
    K = buf_s[0] # Number of frames
    M = buf_s[1] # Number of rows
    N = buf_s[2] # Number of cols
    chan = buf_s[3] # Color channel
    # If this copies data, I'm screwed. 
    %time scikit_buffer = frame_buffer.reshape([K, M*N*chan])
    

我肯定它不是复制数据,因为 reshape 命令以微秒的数量级运行:

CPU 时间:用户 17 μs,系统:1 μs,总计:18 μs挂断时间:21.9 μs

现在我可以在scikit-learn中分析我的框架了!凉!

相关内容

  • 没有找到相关文章

最新更新