2012-10-16 19 views
12

Próba animowania sekwencji obrazów PIL za pomocą tkintera. Wykres moich czasów trwania ramki (ms) wygląda następująco: sawtooth frame durationCzas trwania trąbek piłokształtnych trąbek piłokształtnych?

Ktoś ma pojęcie, co może być przyczyną tego kolczastego wzoru piłokształtnego?

Oto skrypt do reprodukcji:

from PIL import Image, ImageTk 
import Tkinter 

import time 
import sys 

def generate_frames(n): 
    """ 
    keep n under 101 * 101 
    """ 
    out = [] 
    last_pil = None 
    for i in range(n): 
     if last_pil: 
      pil_image = last_pil.copy() 
     else: 
      pil_image = Image.new('L', (101, 101), 255) 
     x = i/101 
     y = i % 101 
     pil_image.load()[x, y] = 0 
     out.append(ImageTk.PhotoImage(pil_image)) 
     last_pil = pil_image 

    return out 

def draw(): 
    FRAME_COUNT =5000 

    master = Tkinter.Tk() 

    w = Tkinter.Canvas(master, width=302, height=302) 
    w.create_rectangle(49, 49, 252, 252) 
    w.pack() 

    frames = generate_frames(FRAME_COUNT) 

    def draw_frame(f, canvas_image): 
     print repr(time.time()) 
     frame = frames[f] 
     if canvas_image is None: 
      canvas_image = w.create_image((151, 151), image=frame, anchor='center') 
     else: 
      w.itemconfigure(canvas_image, image=frame) 

     w.current_frame = frame # save a reference 
     next_frame = f + 1 
     if next_frame < FRAME_COUNT: 
      master.after(1, draw_frame, next_frame, canvas_image) 
     else: 
      sys.exit(0) 

    master.after(10, draw_frame, 0, None) 
    master.mainloop() 


draw() 

Aby zobaczyć wykres, wyjście rury przez

import sys 

last = None 
for line in sys.stdin: 
    value = float(line.strip()) * 1000 
    if last is None: 
     pass 
    else: 
     print (value - last) 
    last = value 

następnie przez

from matplotlib import pyplot 
import sys 

X = [] 
Y = [] 

for index, line in enumerate(sys.stdin): 
    line = line.strip() 
    X.append(index) 
    Y.append(float(line)) 

pyplot.plot(X, Y, '-') 
pyplot.show() 

Making to wielowątkowy nie pomaga :

enter image description here

class AnimationThread(threading.Thread): 

    FRAME_COUNT = 5000 

    def __init__(self, canvas): 
     threading.Thread.__init__(self) 
     self.canvas = canvas 
     self.frames = generate_frames(self.FRAME_COUNT) 

    def run(self): 
     w = self.canvas 
     frames = self.frames 
     canvas_image = None 
     for i in range(self.FRAME_COUNT): 
      print repr(time.time()) 
      frame = frames[i] 
      if canvas_image is None: 
       canvas_image = w.create_image((151, 151), image=frame, anchor='center') 
      else: 
       w.itemconfigure(canvas_image, image=frame) 
      w.current_frame = frame 
      time.sleep(1 * .001) 

def draw_threaded(): 
    FRAME_COUNT = 5000 
    master = Tkinter.Tk() 

    w = Tkinter.Canvas(master, width=302, height=302) 
    w.create_rectangle(49, 49, 252, 252) 
    w.pack() 

    animation_thread = AnimationThread(w) 
    animation_thread.start() 

    master.mainloop() 

    animation_thread.join() 

draw_threaded() 
+0

Chciałbym spróbować uruchomić animację w osobnym wątku nie w głównym wątku i zobacz, co się stanie. –

+0

Dobry pomysł - dzięki. Nie miało to jednak znaczenia (patrz edytowany post). – sobel

+0

Czy próbowałeś profilowania go za pomocą 'python -m cprofile '? –

Odpowiedz

2

To bardzo przypomina ten rodzaj wzoru interferencyjnego konkurując 60 i 50 próbek Hz mieszają:

Interference Pattern of competing 60 Hz and 50 Hz samples

(Original Wolfram|Alpha plot)

Jest to prawdopodobnie spowodowane przez posiadające dwie rzeczy na różnych (ale blisko) częstotliwości odświeżania. To jest to samo, co dzieje się, gdy próbujesz sfilmować ekran telewizora i wygląda na to, że czarny pasek przesuwa się w dół obrazu lub gdy koła samochodu wydają się obracać do tyłu wokół swoich osi w reklamach samochodowych. Jest to zasadniczo rozszerzenie Moiré Effect.

Nie wiem, czy jest to spowodowane przez sterowniki wideo i/lub sprzęt, ale prawie na pewno jest spowodowane zakłóceniami cyklicznymi. Wygląda na to, że cykl GC powinien zakłócać twoją pętlę for (stąd nagły spadek fali podobnej do piłokształtnego, gdy pamięć jest zwalniana i może być przydzielona)

Powiązane problemy