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

eva*_*hin 19 opencv numpy image urllib2 stringio

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

有时我们会遇到图像二值从网址,以避免额外的文件IO,我们要imread从内存缓冲或网址这一形象,但imread只支持从路径文件系统中读取图像.

eva*_*hin 33

要使用内存缓冲区(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)
Run Code Online (Sandbox Code Playgroud)


Pär*_*son 7

As pointed out in the comments to the accepted answer, it is outdated and no longer functional.

Luckily, I had to solve this very problem using Python 3.7 with OpenCV 4.0 recently.

To handle image loading from an URL or an in-memory buffer, I defined the following two functions:

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)
Run Code Online (Sandbox Code Playgroud)

As you can see one depends on the other.

The first one, get_opencv_img_from_buffer, can be used to get an image object from an in-memory buffer. It assumes that the buffer has a read method and that it returns an instance of an object that implements the buffer protocol

The second one, get_opencv_img_from_url, generates an image directly from an URL.

The flags argument is passed on to cv2.imdecode, which has the following constants predefined in cv2:

  • cv2.IMREAD_ANYCOLOR - If set, the image is read in any possible color format.
  • cv2.IMREAD_ANYDEPTH - If set, return 16-bit/32-bit image when the input has the corresponding depth, otherwise convert it to 8-bit.
  • cv2.IMREAD_COLOR - If set, always convert image to the 3 channel BGR color image.
  • cv2.IMREAD_GRAYSCALE - If set, always convert image to the single channel grayscale image (codec internal conversion).
  • 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).