如何让cv2.imread从文件对象或内存流读取图像(例如:未提取的tar)

8 投票
2 回答
13474 浏览
提问于 2025-04-18 16:25

我有一个 .tar 文件,里面装了几百张图片(.png 格式)。我想用 OpenCV 来处理这些图片。

我在想,出于效率考虑,能不能不把这些图片先存到硬盘上,而是直接从内存中读取它们。换句话说,我想从和这个 tar 文件相关的内存流中读取图片。

比如说,

 import tarfile
 import cv2

 tar0 = tarfile.open('mytar.tar')
 im = cv2.imread( tar0.extractfile('fname.png').read() )

最后一行代码不行,因为 imread 需要的是文件名,而不是一个流。

要知道,这种直接从 tar 流中读取的方式是可以做到的,比如处理文本文件(可以参考 这个问题)。


有没有什么建议可以让我用正确的 png 编码打开这个流呢?

当然,把文件解压到内存盘也是一种选择,不过我想找一些更能缓存的方案。

2 个回答

4

也许可以试试用 imdecode 这个方法,配合从tar文件中提取出来的缓冲区?我还没试过,但感觉这个方法很有潜力。

10

感谢@abarry的建议和这个StackOverflow的回答,我终于找到了答案。

请看下面的内容:

def get_np_array_from_tar_object(tar_extractfl):
     '''converts a buffer from a tar file in np.array'''
     return np.asarray(
        bytearray(tar_extractfl.read())
        , dtype=np.uint8)

tar0 = tarfile.open('mytar.tar')

im0 = cv2.imdecode(
        get_np_array_from_tar_object(tar0.extractfile('fname.png'))
        , 0 )

撰写回答