Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read image from in memory buffer (StringIO) or from url with opencv python library

Just share a way to create opencv image object from in memory buffer or from url to improve performance.

Sometimes we get image binary from url, to avoid additional file IO, we want to imread this image from in memory buffer or from url, but imread only supports read image from file system with path.

like image 968
evanchin Avatar asked Nov 11 '12 07:11

evanchin


People also ask

Which OpenCV method is used to read images?

The read() method of the Imgcodecs class is used to read an image using OpenCV.

Which method of OpenCV is used to save images?

OpenCV-Python is a library of Python bindings designed to solve computer vision problems. cv2. imwrite() method is used to save an image to any storage device. This will save the image according to the specified format in current working directory.


2 Answers

To create an OpenCV image object with in memory buffer(StringIO), we can use OpenCV API imdecode, see code below:

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) 
like image 64
evanchin Avatar answered Sep 25 '22 00:09

evanchin


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) 

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).
like image 35
Pärt Johanson Avatar answered Sep 27 '22 00:09

Pärt Johanson