11

I have this simple python script using OpenCV to load images from a folder and display them in a loop. I want to reproduce this effect using matplotlib.

import cv2 as cv
import os

im_files = [for f in os.listdir('.') if f[-3:] == 'png']

for f in im_files:
    im = cv.imread(f, 0) #read image in greyscale
    cv.imshow('display', im)
    cv.waitKey(1)

cv.destroyAllWindows()

I tried the following script but the pyplot window which opens to display the plots becomes un responsive.

import pylab as pl
import os

files = [f for f in os.listdir('.') if f[-3:] == 'png']
pl.ion()
for f in files:
    im=pl.imread(f)
    pl.imshow(im)
    pl.draw()

I have googled a lot but couldn't find any solution. How do I go about doing this? I am using Anaconda 1.6 32bit on Windows 8.

Yash
  • 689
  • 4
  • 11
  • 26
  • http://stackoverflow.com/questions/13595566/matplotlib-qt-imshow-animate – tacaswell Jul 26 '13 at 20:17
  • http://stackoverflow.com/questions/17212722/matplotlib-imshow-how-to-animate – tacaswell Jul 26 '13 at 20:18
  • http://stackoverflow.com/questions/17835302/how-to-update-matplotlibs-imshow-window-interactively/17837600#17837600 – tacaswell Jul 26 '13 at 20:18
  • possible duplicate of [Why does my pylab animation slow down with each update?](http://stackoverflow.com/questions/10272478/why-does-my-pylab-animation-slow-down-with-each-update) – tacaswell Jul 26 '13 at 20:19
  • @tcaswell, thanks for providing the links. This is what I was looking for. – Yash Jul 26 '13 at 20:50

3 Answers3

27
img = None
for f in files:
    im=pl.imread(f)
    if img is None:
        img = pl.imshow(im)
    else:
        img.set_data(im)
    pl.pause(.1)
    pl.draw()
tacaswell
  • 84,579
  • 22
  • 210
  • 199
6

I like the following way of doing this which is really straight-forward and allows the whole figure to be updated, including title, labels etc. rather than just the image.

import numpy as np
from matplotlib import pyplot as plt

for j in range(0,3):
    img = np.random.normal(size=(100,150))
    plt.figure(1); plt.clf()
    plt.imshow(img)
    plt.title('Number ' + str(j))
    plt.pause(3)

A random image is formed.

plt.figure creates the figure the first time round if it does not already exist, and thereafter just makes figure 1 the current figure.

plt.clf clears the figure so subsequent updates don't overlay each other. The image is then displayed with a title.

The plt.pause statement is the key, since this causes the display to be updated - including title, labels etc.

masterfloda
  • 2,908
  • 1
  • 16
  • 27
5

I have implemented a handy script based on matplotlib that just suits your need and much more. Check it here

In your case, the following snippet should work:

import os
from scipy.misc import imread

img_files = [for f in os.listdir('.') if f[-3:] == 'png']

# redraw_fn draw frame f in a image sequence
def redraw_fn(f, axes):
    img_file = img_files[f]
    img = imread(img_file)
    if not redraw_fn.initialized:
        redraw_fn.im = axes.imshow(img, animated=True)
        redraw_fn.initialized = True
    else:
        redraw_fn.im.set_array(img)
redraw_fn.initialized = False

videofig(len(img_files), redraw_fn, play_fps=30)
Bily
  • 751
  • 6
  • 15