【问题标题】:How to read image from in memory buffer (StringIO) or from url with opencv python library如何从内存缓冲区(StringIO)或使用opencv python库的url读取图像
【发布时间】:2012-10-31 00:49:37
【问题描述】:

只需分享一种从内存缓冲区或 url 创建 opencv 图像对象的方法,以提高性能。

有时我们从 url 获取图像二进制文件,为了避免额外的文件 IO,我们希望从内存缓冲区或 url 中imread此图像,但 imread 仅支持从具有路径的文件系统读取图像。

【问题讨论】:

    标签: image opencv numpy urllib2 stringio


    【解决方案1】:

    要使用内存缓冲区(StringIO)创建一个 OpenCV 图像对象,我们可以使用 OpenCV API imdecode,见下面的代码:

    import cv2
    import numpy as np
    from urllib2 import urlopen
    from cStringIO import StringIO
    
    def create_opencv_image_from_stringio(img_stream, cv2_img_flag=0):
        img_stream.seek(0)
        img_array = np.asarray(bytearray(img_stream.read()), dtype=np.uint8)
        return cv2.imdecode(img_array, cv2_img_flag)
    
    def create_opencv_image_from_url(url, cv2_img_flag=0):
        request = urlopen(url)
        img_array = np.asarray(bytearray(request.read()), dtype=np.uint8)
        return cv2.imdecode(img_array, cv2_img_flag)
    

    【讨论】:

    • 如果图像无法解码,则返回 None。我必须从阻止 opencv 解码的字符串的开头添加删除一个 'data:image/png;base64'。
    • 第二个答案我见过这样的,但它对我不起作用。我不敢相信将图像从 URL 加载到 open-cv 会是这样一个问题
    • imread 给了我一个TypeError: expected string or Unicode object, numpy.ndarray found 错误。
    【解决方案2】:

    正如 cmets 对已接受答案的指出,它已过时且不再起作用。

    幸运的是,我最近不得不使用 Python 3.7 和 OpenCV 4.0 解决这个问题。

    为了处理从 URL 或内存缓冲区加载的图像,我定义了以下两个函数:

    import urllib.request
    import cv2
    import numpy as np
    
    def get_opencv_img_from_buffer(buffer, flags):
        bytes_as_np_array = np.frombuffer(buffer.read(), dtype=np.uint8)
        return cv2.imdecode(bytes_as_np_array, flags)
    
    def get_opencv_img_from_url(url, flags):
        req = urllib.request.Request(url)
        return get_opencv_img_from_buffer(urllib.request.urlopen(req), flags)
    

    如您所见,一个依赖于另一个。

    第一个,get_opencv_img_from_buffer,可用于从内存缓冲区中获取图像对象。它假定缓冲区有一个读取方法,并且它返回一个实现the buffer protocol的对象的实例@

    第二个 get_opencv_img_from_url 直接从 URL 生成图像。

    flags 参数被传递给 cv2.imdecode, 它在 cv2 中预定义了以下常量:

    • cv2.IMREAD_ANYCOLOR - 如果设置,则以任何可能的颜色格式读取图像。
    • cv2.IMREAD_ANYDEPTH - 如果设置,则在输入具有相应深度时返回 16 位/32 位图像,否则将其转换为 8 位。
    • cv2.IMREAD_COLOR - 如果设置,则始终将图像转换为 3 通道 BGR 彩色图像。
    • cv2.IMREAD_GRAYSCALE - 如果设置,则始终将图像转换为单通道灰度图像(编解码器内部转换)。
    • cv2.IMREAD_IGNORE_ORIENTATION - 如果设置,则不要根据 EXIF 的方向标志旋转图像。
    • cv2.IMREAD_LOAD_GDAL - 如果设置,则使用 gdal 驱动程序加载图像。
    • cv2.IMREAD_REDUCED_COLOR_2 - 如果设置,则始终将图像转换为 3 通道 BGR 彩色图像,并且图像尺寸缩小 1/2。
    • cv2.IMREAD_REDUCED_COLOR_4 - 如果设置,则始终将图像转换为 3 通道 BGR 彩色图像,图像尺寸缩小 1/4。
    • cv2.IMREAD_REDUCED_COLOR_8 - 如果设置,则始终将图像转换为 3 通道 BGR 彩色图像,并且图像尺寸缩小 1/8。
    • cv2.IMREAD_REDUCED_GRAYSCALE_2 - 如果设置,则始终将图像转换为单通道灰度图像,图像尺寸缩小 1/2。
    • cv2.IMREAD_REDUCED_GRAYSCALE_4 - 如果设置,则始终将图像转换为单通道灰度图像,图像尺寸缩小 1/4。
    • cv2.IMREAD_REDUCED_GRAYSCALE_8 - 如果设置,则始终将图像转换为单通道灰度图像,图像尺寸缩小 1/8。
    • cv2.IMREAD_UNCHANGED - 如果设置,则按原样返回加载的图像(使用 Alpha 通道,否则会被裁剪)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-21
      • 1970-01-01
      • 1970-01-01
      • 2016-02-18
      • 1970-01-01
      • 2013-07-23
      • 1970-01-01
      • 2019-06-30
      相关资源
      最近更新 更多