分享一种从内存缓冲区或URL创建OpenCV图像对象的方法,以提高性能。
有时我们从URL获取图像二进制数据,为了避免额外的文件IO,我们想从内存缓冲区或URL中imread读取该图像,但是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中预定义了以下常量:
TypeError: expected string or Unicode object, numpy.ndarray found
错误。 - bittterbotter