27

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

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

4

2 回答 2

41

要使用内存缓冲区(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)
于 2012-11-11T07:42:46.310 回答
17

正如对已接受答案的评论中指出的那样,它已经过时并且不再起作用。

幸运的是,我最近不得不使用 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 中预定义了以下常量:

  • cv2.IMREAD_ANYCOLOR - 如果设置,图像以任何可能的颜色格式读取。
  • cv2.IMREAD_ANYDEPTH - 如果设置,则在输入具有相应深度时返回 16 位/32 位图像,否则将其转换为 8 位。
  • cv2.IMREAD_COLOR - 如果设置,总是将图像转换为 3 通道 BGR 彩色图像。
  • cv2.IMREAD_GRAYSCALE - 如果设置,总是将图像转换为单通道灰度图像(编解码器内部转换)。
  • cv2.IMREAD_IGNORE_ORIENTATION - If set, do not rotate the image according to EXIF's orientation flag.
  • cv2.IMREAD_LOAD_GDAL - If set, use the gdal driver for loading the image.
  • cv2.IMREAD_REDUCED_COLOR_2 - If set, always convert image to the 3 channel BGR color image and the image size reduced 1/2.
  • cv2.IMREAD_REDUCED_COLOR_4 - If set, always convert image to the 3 channel BGR color image and the image size reduced 1/4.
  • cv2.IMREAD_REDUCED_COLOR_8 - If set, always convert image to the 3 channel BGR color image and the image size reduced 1/8.
  • cv2.IMREAD_REDUCED_GRAYSCALE_2 - If set, always convert image to the single channel grayscale image and the image size reduced 1/2.
  • cv2.IMREAD_REDUCED_GRAYSCALE_4 - If set, always convert image to the single channel grayscale image and the image size reduced 1/4.
  • cv2.IMREAD_REDUCED_GRAYSCALE_8 - If set, always convert image to the single channel grayscale image and the image size reduced 1/8.
  • cv2.IMREAD_UNCHANGED - If set, return the loaded image as is (with alpha channel, otherwise it gets cropped).
于 2019-03-26T15:14:04.050 回答