Quiero trazar una secuencia de imágenes .png en matplotlib. El objetivo es trazarlos rápidamente para simular el efecto de una película, pero tengo razones adicionales para querer evitar crear un archivo .avi o guardar figuras matplotlib y luego verlas en secuencia fuera de Python.
Estoy tratando específicamente de ver los archivos de imagen en secuencia dentro de un ciclo for en Python. Suponiendo que he importado matplotlib correctamente, y tengo mis propias funciones 'new_image ()' y 'new_rect ()', aquí hay un código de ejemplo que no funciona debido al efecto de bloqueo de la llamada de la función show () al bucle principal de la GUI:
for index in index_list:
img = new_image(index)
rect = new_rect(index)
plt.imshow(img)
plt.gca().add_patch(rect)
plt.show()
#I also tried pausing briefly and then closing, but this doesn't
#get executed due to the GUI mainloop from show()
time.sleep(0.25)
plt.close()
El código anterior funciona para mostrar solo la primera imagen, pero luego el programa simplemente se cuelga y espera a que cierre manualmente la ventana de la figura resultante. Una vez que lo cierro, el programa simplemente se cuelga y no se vuelve a trazar con los nuevos datos de imagen. ¿Qué debería estar haciendo? También tenga en cuenta que he intentado reemplazar el comando plt.show () con un comando plt.draw () y luego agregar el plt.show () fuera del ciclo for. Esto no muestra nada y simplemente se cuelga.
3 respuestas
La mejor manera que he encontrado para esto fue con el comando pylab.ion()
después de importar pylab.
Aquí hay una secuencia de comandos que usa show()
, pero que muestra las diferentes parcelas cada vez que se llama a pylab.draw()
, y que deja las ventanas de la trama mostrando indefinidamente. Utiliza una lógica de entrada simple para decidir cuándo cerrar las cifras (porque usar show()
significa que pylab no procesará clics en el botón x de Windows), pero eso debería ser simple de agregar a su interfaz gráfica de usuario como otro botón o como campo de texto.
import numpy as np
import pylab
pylab.ion()
def get_fig(fig_num, some_data, some_labels):
fig = pylab.figure(fig_num,figsize=(8,8),frameon=False)
ax = fig.add_subplot(111)
ax.set_ylim([0.1,0.8]); ax.set_xlim([0.1, 0.8]);
ax.set_title("Quarterly Stapler Thefts")
ax.pie(some_data, labels=some_labels, autopct='%1.1f%%', shadow=True);
return fig
my_labels = ("You", "Me", "Some guy", "Bob")
# To ensure first plot is always made.
do_plot = 1; num_plots = 0;
while do_plot:
num_plots = num_plots + 1;
data = np.random.rand(1,4).tolist()[0]
fig = get_fig(num_plots,data,my_labels)
fig.canvas.draw()
pylab.draw()
print "Close any of the previous plots? If yes, enter its number, otherwise enter 0..."
close_plot = raw_input()
if int(close_plot) > 0:
pylab.close(int(close_plot))
print "Create another random plot? 1 for yes; 0 for no."
do_plot = raw_input();
# Don't allow plots to go over 10.
if num_plots > 10:
do_plot = 0
pylab.show()
Al modificar la lógica básica aquí, puedo hacer que cierre ventanas y grafique imágenes consecutivamente para simular la reproducción de una película, o puedo mantener el control del teclado sobre cómo avanza a través de la película.
Nota: esto me ha funcionado en todas las plataformas y parece estrictamente superior al enfoque del administrador del lienzo de ventana anterior, y no requiere la opción 'TkAgg'.
He implementado un útil script que se adapta a tus necesidades. Pruébelo aquí
A continuación se muestra un ejemplo que muestra imágenes junto con su cuadro delimitador:
import os
import glob
from scipy.misc import imread
from matplotlib.pyplot import Rectangle
video_dir = 'YOUR-VIDEO-DIRECTORY'
img_files = glob.glob(os.path.join(video_dir, '*.jpg'))
box_files = glob.glob(os.path.join(video_dir, '*.txt'))
def redraw_fn(f, axes):
img = imread(img_files[f])
box = bbread(box_files[f]) # Define your own bounding box reading utility
x, y, w, h = box
if not redraw_fn.initialized:
im = axes.imshow(img, animated=True)
bb = Rectangle((x, y), w, h,
fill=False, # remove background
edgecolor="red")
axes.add_patch(bb)
redraw_fn.im = im
redraw_fn.bb = bb
redraw_fn.initialized = True
else:
redraw_fn.im.set_array(img)
redraw_fn.bb.set_xy((x, y))
redraw_fn.bb.set_width(w)
redraw_fn.bb.set_height(h)
redraw_fn.initialized = False
videofig(len(img_files), redraw_fn, play_fps=30)
Basado en http://matplotlib.sourceforge.net/examples/animation/simple_anim_tkagg.html:
import time
import numpy as np
import matplotlib
matplotlib.use('TkAgg') # do this before importing pylab
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
def animate():
tstart = time.time() # for profiling
data=np.random.randn(10,10)
im=plt.imshow(data)
for i in np.arange(1,200):
data=np.random.randn(10,10)
im.set_data(data)
fig.canvas.draw() # redraw the canvas
print 'FPS:' , 200/(time.time()-tstart)
win = fig.canvas.manager.window
fig.canvas.manager.window.after(100, animate)
plt.show()
plt.imshow
puede aceptar una matriz flotante, una matriz uint8 o una imagen PIL. Entonces, si tiene un directorio de archivos PNG, puede abrirlos como imágenes PIL y animarlos así:
import matplotlib
matplotlib.use('TkAgg') # do this before importing pylab
import matplotlib.pyplot as plt
import Image
import glob
fig = plt.figure()
ax = fig.add_subplot(111)
def animate():
filenames=sorted(glob.glob('*.png'))
im=plt.imshow(Image.open(filenames[0]))
for filename in filenames[1:]:
image=Image.open(filename)
im.set_data(image)
fig.canvas.draw()
win = fig.canvas.manager.window
fig.canvas.manager.window.after(100, animate)
plt.show()
Preguntas relacionadas
Preguntas vinculadas
Nuevas preguntas
python
Python es un lenguaje de programación multipropósito, de tipificación dinámica y de múltiples paradigmas. Está diseñado para ser rápido de aprender, comprender y usar, y hacer cumplir una sintaxis limpia y uniforme. Tenga en cuenta que Python 2 está oficialmente fuera de soporte a partir del 01-01-2020. Aún así, para preguntas de Python específicas de la versión, agregue la etiqueta [python-2.7] o [python-3.x]. Cuando utilice una variante de Python (por ejemplo, Jython, PyPy) o una biblioteca (por ejemplo, Pandas y NumPy), inclúyala en las etiquetas.