Python 将图像读取到预先分配的numpy阵列

Python 将图像读取到预先分配的numpy阵列,python,numpy,opencv,Python,Numpy,Opencv,我正在用Python(使用Numpy/Scipy+OpenCV)进行一些快速图像处理。 有几千张图像是完全相同的形状-一旦我读了第一张,我就确切地知道所有其他图像的样子 问题是从磁盘读取下一个图像会导致分配新内存(速度很慢)。有没有办法通过将下一幅图像直接读入一些已经存在的内存(ndarray)来避免这种情况?我知道C++中的哪一个可以接受一个指针来分配预先分配的Mat,但是它似乎没有Python绑定(唯一的选项是返回一个全新的数组)。 我需要这个用于多处理-我想将图像读入共享内存,然后在工作进

我正在用Python(使用Numpy/Scipy+OpenCV)进行一些快速图像处理。 有几千张图像是完全相同的形状-一旦我读了第一张,我就确切地知道所有其他图像的样子

问题是从磁盘读取下一个图像会导致分配新内存(速度很慢)。有没有办法通过将下一幅图像直接读入一些已经存在的内存(
ndarray
)来避免这种情况?我知道C++中的哪一个可以接受一个指针来分配预先分配的Mat,但是它似乎没有Python绑定(唯一的选项是返回一个全新的数组)。 我需要这个用于多处理-我想将图像读入共享内存,然后在工作进程中对它们进行一些繁重的工作。现在,我不得不将分配的数组中的数据复制到共享内存中,这同样需要时间。我希望能够直接在那里写作

height, width = (50, 50)
image = np.zeros((height, width))
id(image)
# outputs: 140411457307552
image[:, :] = np.ones((height, width))
id(image)
# outputs: 140411457307552
image = np.ones((height, width))
id(image)
# outputs -> 140411437723280

# when reading from disk (assuming your images are 50x50 pixels)
image[:, :] = cv2.imread("/home/.../your_im_50x50.png")
通过寻址每个图像的维度,python将尝试将给定数组存储到现有数组中。这将导致内存分配到预先分配的内存区域。如果数组的形状不同,则会引发ValueError。
当只提到变量名时,会创建一个对数组的新引用,从而在内存中产生一个新对象(cf id)

虽然这是一个很好的提示,但它完全忽略了我想从磁盘读取数据并将其直接放入内存的事实。但是,您让我意识到我的问题可能更清楚,因此我对其进行了相应的编辑。cv2.imread返回numpy.ndarray对象。这就是为什么做
image[:,:]=np.ones(…)
image[:,:]=cv2.imread(“/home/../your_im.png”)
是完全一样的,这就是为什么你没有抓住问题的关键。
imread
调用已经创建了新的缓冲区。花里胡哨的抄袭并不能让你摆脱困境。您也可以直接删除旧的缓冲区,然后用新的缓冲区替换。这听起来像是OpenCV的一个有用的PR。您使用的是什么文件格式?可能会使用较低级别的库之一。您是否有探查器数据显示您的瓶颈确实在内存分配中?如果是这样的话,为什么不慢慢地将图像读入一个张量,并将该张量缓存到磁盘?@NilsWerner内存分配并不是唯一的瓶颈。它也是复制到子进程,它对图像进行一些处理——在通过管道发送数据期间,或者在从OpenCV分配的缓冲区复制到共享内存期间。我希望将数据直接读取到共享内存中,一石二鸟同时杀死分配和复制鸟;)现在我正在使用PNG,但最终我希望有一个更通用的解决方案。我也面临同样的问题。我想将帧捕获到预先分配的numpy数组中。你能告诉我你的解决方案吗?现在,我必须编写一个C扩展来调用C/C++api,并包装一个接受numpy缓冲区指针的新函数。