【发布时间】:2012-10-31 00:49:37
【问题描述】:
只需分享一种从内存缓冲区或 url 创建 opencv 图像对象的方法,以提高性能。
有时我们从 url 获取图像二进制文件,为了避免额外的文件 IO,我们希望从内存缓冲区或 url 中imread此图像,但 imread 仅支持从具有路径的文件系统读取图像。
【问题讨论】:
标签: image opencv numpy urllib2 stringio
只需分享一种从内存缓冲区或 url 创建 opencv 图像对象的方法,以提高性能。
有时我们从 url 获取图像二进制文件,为了避免额外的文件 IO,我们希望从内存缓冲区或 url 中imread此图像,但 imread 仅支持从具有路径的文件系统读取图像。
【问题讨论】:
标签: image opencv numpy urllib2 stringio
要使用内存缓冲区(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)
【讨论】:
TypeError: expected string or Unicode object, numpy.ndarray found 错误。
正如 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 中预定义了以下常量:
【讨论】: