14

I can read jpg file using cv2 as

import cv2
import numpy as np
import urllib
url = r'http://www.mywebsite.com/abc.jpg'
req = urllib.request.urlopen(url)
arr = np.asarray(bytearray(req.read()), dtype=np.uint8)
img = cv2.imdecode(arr,-1)
cv2.imshow('abc',img)

However, when I do it with gif file, it returns an error:

error: (-215) size.width>0 && size.height>0 in function cv::imshow

How to solve this problem?

Kinght 金
  • 17,681
  • 4
  • 60
  • 74
Chan
  • 3,605
  • 9
  • 29
  • 60
  • As far as I know, OpenCV does not support GIF files... try using PIL (pillow) to load it and then pass it to OpenCV. [Here](https://stackoverflow.com/questions/7391945/how-do-i-read-image-data-from-a-url-in-python) you have another question about how to get an image with PIL and [this one](https://stackoverflow.com/questions/14134892/convert-image-from-pil-to-opencv-format) to convert to OpenCV – api55 Jan 09 '18 at 07:57
  • Thank you very much, api55. – Chan Jan 09 '18 at 09:04

1 Answers1

22

Steps:

  1. Use urllib to read the gif from web,
  2. Use imageio.mimread to load the gif to nump.ndarray(s).
  3. Change the channels orders by numpy or OpenCV.
  4. Do other image-processing using OpenCV

Code example:

import imageio
import urllib.request

url = "https://i.stack.imgur.com/lui1A.gif"
fname = "tmp.gif"

## Read the gif from the web, save to the disk
imdata = urllib.request.urlopen(url).read()
imbytes = bytearray(imdata)
open(fname,"wb+").write(imdata)

## Read the gif from disk to `RGB`s using `imageio.miread` 
gif = imageio.mimread(fname)
nums = len(gif)
print("Total {} frames in the gif!".format(nums))

# convert form RGB to BGR 
imgs = [cv2.cvtColor(img, cv2.COLOR_RGB2BGR) for img in gif]

## Display the gif
i = 0

while True:
    cv2.imshow("gif", imgs[i])
    if cv2.waitKey(100)&0xFF == 27:
        break
    i = (i+1)%nums
cv2.destroyAllWindows()

Note. I use the gif in my another answer. Video Stabilization with OpenCV

The result:

>>> Total 76 frames!

One of the gif-frames displayed:

enter image description here

Kinght 金
  • 17,681
  • 4
  • 60
  • 74
  • 1
    You can also use the library gif2numpy. You can find it at https://github.com/bunkahle/gif2numpy – bunkus Apr 15 '19 at 04:57
  • @bunkus I check your library `gif2numpy`. It's a nice library based on `kaitaistruct` binary struct descriptor. And it'll be better if it supports multi-frames gif. Great job! – Kinght 金 Apr 15 '19 at 06:16
  • Well it now supports also multiple frames. Give it a try and let me know if it works for you – bunkus Apr 21 '19 at 13:17
  • @bunkus I try to use [git2numpy](https://github.com/bunkahle/gif2numpy) to read a multi-frames gif(such as Images/Rotating_earth.gif), it successfully read 44 frames. Nice. While, there exists one issue, I'll comment on the project. Thank you for you job. – Kinght 金 Apr 22 '19 at 01:29
  • gif2numpy has been bugfixed in version 1.2. Images now come out without missing pixels, latest version on github: https://github.com/bunkahle/gif2numpy – bunkus Apr 24 '19 at 05:14
  • @bunkus `Now, the gif2numpy works fine for multi-frames gif` except the time costing 60ms(imageio) vs 6000ms(gif2numpy). And `jit(numba)`、 `vector operation(numpy)` 、`Cython or C` will accelerate the parsing speed. You can add a new answer using `gif2numpy` under this SO question. – Kinght 金 Apr 24 '19 at 06:17