Image 如何使用opencv python库从内存缓冲区(StringIO)或url读取图像

Image 如何使用opencv python库从内存缓冲区(StringIO)或url读取图像,image,opencv,numpy,urllib2,stringio,Image,Opencv,Numpy,Urllib2,Stringio,只需共享一种从内存缓冲区或url创建opencv图像对象的方法,即可提高性能 有时我们从url获取图像二进制文件,为了避免额外的文件IO,我们希望从内存缓冲区或url读取此图像,但imread仅支持从文件系统读取具有路径的图像。要创建具有内存缓冲区(StringIO)的OpenCV图像对象,我们可以使用OpenCV API imdecode,请参阅下面的代码: import cv2 import numpy as np from urllib2 import urlopen from cStri

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


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

要创建具有内存缓冲区(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)

正如对公认答案的评论所指出的,它已经过时,不再起作用

幸运的是,最近我不得不使用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)
正如你所看到的,一个依赖于另一个

第一种方法是从缓冲区获取opencv\img\U,可用于从内存缓冲区获取图像对象。它假设缓冲区有一个read方法,并返回一个实现该方法的对象实例

第二个,从url获取opencv\img\U,直接从url生成图像

flags参数被传递到cv2.imdecode, 具有cv2中预定义的以下常量:

  • cv2.IMREAD\U ANYCOLOR-如果设置,则以任何可能的颜色格式读取图像
  • cv2.IMREAD_ANYDEPTH-如果设置,则在输入具有相应深度时返回16位/32位图像,否则将其转换为8位
  • cv2.IMREAD_COLOR-如果已设置,请始终将图像转换为3通道BGR彩色图像
  • cv2.IMREAD_灰度-如果设置,则始终将图像转换为单通道灰度图像(编解码器内部转换)
  • cv2.IMREAD_IGNORE_方向-如果设置,请勿根据EXIF的方向标志旋转图像
  • cv2.IMREAD\U LOAD\U GDAL-如果设置,请使用GDAL驱动程序加载图像
  • cv2.IMREAD_REDUCTED_COLOR_2-如果设置,请始终将图像转换为3通道BGR彩色图像,并且图像大小减小1/2
  • cv2.IMREAD\u REDUCED\u COLOR\u 4-如果设置,请始终将图像转换为3通道BGR彩色图像,并将图像大小缩小1/4
  • cv2.IMREAD_REDUCTED_COLOR_8-如果设置,请始终将图像转换为3通道BGR彩色图像,并且图像大小减小1/8
  • cv2.IMREAD\u REDUCED\u GRAYSCALE\u 2-如果设置,请始终将图像转换为单通道灰度图像,并将图像大小缩小1/2
  • cv2.IMREAD\u REDUCED\u GRAYSCALE\u 4-如果设置,请始终将图像转换为单通道灰度图像,并将图像大小缩小1/4
  • cv2.IMREAD\u REDUCED\u GRAYSCALE\u 8-如果设置,请始终将图像转换为单通道灰度图像,并将图像大小缩小1/8
  • cv2.IMREAD_UNCHANGED-如果设置,则按原样返回加载的图像(使用alpha通道,否则将被裁剪)

如果图像无法解码,则返回“无”。我不得不添加或删除一个'data:image/png;base64,`从阻止opencv解码的字符串的开头开始。第二个答案我看到过,但它对我不起作用。我不敢相信将一个图像从URL加载到open cvimread中会出现这样的问题,这给了我一个
类型错误:预期的字符串或Unicode对象,numpy.ndarray found
错误。