从 url 读取图像的最快方法是什么?

Cri*_*ivo 5 python url image keras

我想制作一个生成器,从 url 生成批量图像来训练keras模型。我有另一个生成器可以为我提供图像 url。

我目前所做的是将图像下载到磁盘,然后从磁盘加载图像。

def loadImage(URL):
    with urllib.request.urlopen(URL) as url:
        with open('temp.jpg', 'wb') as f:
            f.write(url.read())

    img_path = 'temp.jpg'
    img = image.load_img(img_path, target_size=(125, 125))
    os.remove(img_path)
    x = image.img_to_array(img)
    return x

def imageGenerator(batch_size):
    i = 0
    batch = []
    for URL in imageUrlGenerator():
        if i>batch_size:
            yield batch
            batch = []
            i=0
        batch.append(loadImage(URL))
        i+=1
Run Code Online (Sandbox Code Playgroud)

这有效,但我想知道是否没有更快的方法来从网络加载图像而无需写入和读取磁盘。

met*_*ter 7

假设您实际上正在使用keras并且这image.load_img是您正在调用的方法,它会调用一个最终应该是PIL.Image.open. 在该文件PIL.image.open中,第一个参数fp可以是一个字符串的文件名(这是目前你逝去的是什么),或流状物体实现readseektell。虽然返回的对象urllib.request.urlopen确实提供了所有三个方法,但它根本没有实现seek,因此不能直接使用。但是,整个缓冲区可以读入一个BytesIO实现了的对象seek,所以它应该是可用的。将这些放在一起,您的loadImage功能可能会简化为以下内容:

from io import BytesIO

def loadImage(URL):
    with urllib.request.urlopen(URL) as url:
        img = image.load_img(BytesIO(url.read()), target_size=(125, 125))

    return image.img_to_array(img)
Run Code Online (Sandbox Code Playgroud)

这使下载的图像完全保留在内存中。

  • 更重要的是:它不再适用于 URL 字符串:`TypeError:预期的 str、bytes 或 os.PathLike 对象,而不是 _io.BytesIO`:https://github.com/keras-team/keras-preprocessing/问题/293 (5认同)

小智 6

这是我见过的最简单的解决方案。

from PIL import Image
from urllib import request
from io import BytesIO

url = "https://github.com/ironmanciti/MachineLearningBasic/blob/master/datasets/TransferLearningData/watch.jpg?raw=true"
res = request.urlopen(url).read()
Sample_Image = Image.open(BytesIO(res)).resize((150,150))

plt.imshow(Sample_Image)
Run Code Online (Sandbox Code Playgroud)