只需分享一种从内存缓冲区或 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)
如您所见,一个依赖于另一个。
第一个,get_opencv_img_from_buffer,可用于从内存缓冲区中获取图像对象。它假定缓冲区有一个读取方法,并且它返回一个实现缓冲区协议的对象的实例
第二个,get_opencv_img_from_url,直接从 URL 生成图像。
flags 参数被传递给 cv2.imdecode,它在 cv2 中预定义了以下常量: