7

I am able to successfully load an image from a zip:

with zipfile.ZipFile('test.zip', 'r') as zfile:
    data = zfile.read('test.jpg')
    # how to open this using imread or imdecode?

The question is: how can I open this using imread or imdecode for further processing in opencv without saving the image first?

Update:

Here the expected errors I get. I need to convert 'data' into a type that can be consumed by opencv.

data = zfile.read('test.jpg')
buf = StringIO.StringIO(data)
im = cv2.imdecode(buf, cv2.IMREAD_GRAYSCALE)
# results in error: TypeError: buf is not a numpy array, neither a scalar

a = np.asarray(buf)
cv2.imdecode(a, cv2.IMREAD_GRAYSCALE)
# results in error: TypeError: buf data type = 17 is not supported
IUnknown
  • 2,596
  • 4
  • 35
  • 52

2 Answers2

20

use numpy.frombuffer() to create a uint8 array from the string:

import zipfile
import cv2
import numpy as np

with zipfile.ZipFile('test.zip', 'r') as zfile:
    data = zfile.read('test.jpg')

img = cv2.imdecode(np.frombuffer(data, np.uint8), 1)    
iljau
  • 2,151
  • 3
  • 22
  • 45
HYRY
  • 94,853
  • 25
  • 187
  • 187
-1

HYRY's answer does indeed provide the most elegant solution


Reading images in Python doesn't quite comply with "There should be one-- and preferably only one --obvious way to do it."

It is possible that sometimes you'd rather avoid using numpy in some parts of your application. And use Pillow or imread instead. If one day you find yourself in such situation, then hopefully following code snippet will be of some use:

import zipfile

with zipfile.ZipFile('test.zip', 'r') as zfile:
    data = zfile.read('test.jpg')

# Pillow
from PIL import Image
from StringIO import StringIO
import numpy as np
filelike_buffer = StringIO(data)
pil_image = Image.open(filelike_buffer)
np_im_array_from_pil = np.asarray(pil_image)
print type(np_im_array_from_pil), np_im_array_from_pil.shape
# <type 'numpy.ndarray'> (348, 500, 3)

# imread
from imread import imread_from_blob
np_im_array = imread_from_blob(data, "jpg")
print type(np_im_array), np_im_array.shape
# <type 'numpy.ndarray'> (348, 500, 3)

Answer to "How to read raw png from an array in python opencv?" provides similar solution.

Community
  • 1
  • 1
iljau
  • 2,151
  • 3
  • 22
  • 45
  • oh, noes, that'll try to make an unicode string of something, that's actually a byte array – berak Jan 25 '14 at 22:54
  • @berak you may want to check out answer to ["UnicodeDecodeError: 'ascii' codec can't decode"](http://stackoverflow.com/a/6541289/2419207) – iljau Jan 25 '14 at 22:59