Python字符串作为Skimage imread中的文件



我正在Kaggle上进行CIFAR挑战。

他们提供了一个.7z的文件,其中包含5万张火车照片。我花了1个小时解压缩它,然后又花了40分钟读取所有文件并将其存储在内存中。

尽量不创建50k文件,因为这是它的瓶颈,我已经安装了pylzma和其他库,但所有这些库都会告诉我该文件无效。

来自bash的7z,可以正确读取文件,并列出文件。因此,我使用Popen解压缩所有文件,并使用bash7z程序将其放入内存中的字符串中

import subprocess
p = subprocess.Popen(["7z", "e", "-so", "awa.7z"], stdout=subprocess.PIPE).communicate()[0]

我通过查看每个文件的大小,然后从字符串中获得适当的字节,成功地分别获得了每个文件

f1 = p[0][0:2105]

我现在想要的是让Python思考F1文件指针,这样我就可以调用skimage.io.imread,它将转换为合适的结构。或者只需将内存值传递给skimage,它就会为我进行转换。

虽然skimage.io.imread的doc说第一个参数是文件名的字符串,但我发现它也接受类似文件的对象(skimage版本为0.10.0)

所以你可以像这样把图像数据读入内存:

from StringIO import StringIO
with open(filename) as f:
    img_data = f.read()
decoded_img_data = skimage.io.imread(StringIO(img_data))
print decoded_img_data
>> OUTPUT:
array([[[235, 230, 234],
        [233, 228, 232],
        [231, 226, 230],
        ...,

skimage.io.imread()的第一个参数是要读取的图像文件的名称,因此您无法使用字符串中的图像数据来欺骗它。选项(按方便顺序):

  • 直接使用imread软件包-请参阅imread.imread_from_blob()。这将返回一个numpy.ndarray(与skimage.io.imread相同)。您需要知道图像文件类型(jpg、png、gif等),因为这必须作为第二个参数传递:

    from imread import imread_from_blob
    img_data = imread_from_blob(f1, 'jpg')
    >>> img_data
    array([[[ 23, 123, 149],
    [ 22, 120, 147],
    [ 22, 118, 143],
    ...,
    etc.
    
  • 将数据写入临时文件,然后使用imread()打开该临时文件。imread()在处理URL时会自己执行此操作。

  • 使用命名管道。使用imread()打开管道进行读取,然后将数据写入管道。您可能需要线程或多处理来完成此操作

浏览skimage代码,我发现它们可以与另一个图像库PIL集成。这个库有一个函数,可以直接从打开的文件指针中获取图像信息。

在我的例子中,文件指针是StringIO,所以它可以读取数据并识别它的内容。

霍克,谢谢你的帮助。在我看来,你的解决方案也会起作用,但我不想处理图像数据本身。

我已经把代码放在github中了(它只是一个骨架,但可以工作),如果有人感兴趣,下面是精彩的页面http://adrianow.github.io/7z_on_array/

下面是解决方案的一个简短部分:

import numpy as np
from PIL import Image
from StringIO import StringIO
# begin and end of each file
low = 0
up = 0
images = [0] *len(p_f_list)
# get each file from the byte file
for i, f in enumerate(p_f_list):
    up += int(f[0])
    # get bytes from the array
    raw_img = p_f_data.data[low:up]
    low = up
    # Convert rawImage to Mat
    pil_image = Image.open(StringIO(raw_img))
    np_image = np.array(pil_image)
    images[i] = np_image

最新更新