tkinter - Cache overflowing while showing an image stream using python 3 on a Raspberry Pi 2 Model B running Jessie and up to date -


i’m new python. i’m working on ‘proof of concept’ piece of code; using picamera on raspberry pi running jessie.

i’ve based code on tutorial code from: https://pythonprogramming.net/tkinter-adding-text-images/

once hit button show image, code starts picamera , starts capture_continuous, passes stream, applies crosshairs it.

it works well… after bit on 2 minutes, disk drive lights , starts slow drastically. once program break, fine. i’ve looked @ couple of logs, can’t life of me find out cache overflowing or why. i’ve tried bunch of different ways , tried leave in comments. suspected had having clear image in tkinter, doesn’t seem work , makes video flash unevenly.

any great! i’ve started explore using opencv instead. still installing that.

thanks!

the code:

# simple enough, import tkinter. tkinter import * import picamera import picamera.array import time import threading import io import numpy np  pil import image, imagetk   # here, creating our class, window, , inheriting frame # class. frame class tkinter module. (see lib/tkinter/__init__) class window(frame):      # create array representing 1280x720 image of     # cross through center of display. shape of     # array must of form (height, width, color)       # define settings upon initialization. here can specify     def __init__(self, master=none):          # parameters want send through frame class.          frame.__init__(self, master)             #reference master widget, tk window                          self.master = master          #with that, want run init_window, doesn't yet exist         self.init_window()      #creation of init_window     def init_window(self):          # changing title of our master widget               self.master.title("gui")          # allowing widget take full space of root window         self.pack(fill=both, expand=1)          # creating menu instance         menu = menu(self.master)         self.master.config(menu=menu)          # create file object)         file = menu(menu)          # adds command menu option, calling exit, ,         # command runs on event client_exit         file.add_command(label="exit", command=self.client_exit)          #added "file" our menu         menu.add_cascade(label="file", menu=file)           # create file object)         edit = menu(menu)          # adds command menu option, calling exit, ,         # command runs on event client_exit         edit.add_command(label="show img", command=self.showimg)         edit.add_command(label="show text", command=self.showtext)          #added "file" our menu         menu.add_cascade(label="edit", menu=edit)          self.trim_running_bool = false      def showimg(self):         self.trim_running_bool = true         trim_thrd_thread = threading.thread(target=self._cam_thread_def)         trim_thrd_thread.start()         self.update_idletasks()       def _cam_thread_def(self):          img_stream = io.bytesio()         frame_count = 0          picamera.picamera() camera:             camera.resolution = (400, 300)  ##            while true:   ### tried way             xxx in range(0,900):                 img_stream = io.bytesio()                 frame_count = frame_count + 1                 print(frame_count,"   ", xxx)                 if self.trim_running_bool == false:                     print("break")                     break                 camera.capture(img_stream, 'jpeg', use_video_port=true)                 img_stream.seek(0)                 img_load = image.open(img_stream)                    xl_line in range(0,196,4):                     img_load.putpixel((xl_line, 149), (xl_line, 0, 0))                     xll=xl_line+2                     img_load.putpixel((xl_line, 150), (xl_line, xl_line, xl_line))                     img_load.putpixel((xl_line, 151), (xl_line, 0, 0))                     (xl_line)                  xr_line in range(208,400,4):                     clr = 400 - xr_line                     img_load.putpixel((xr_line, 149), (clr, 0, 0))                     img_load.putpixel((xr_line, 150), (clr, clr, clr))                     img_load.putpixel((xr_line, 151), (clr, 0, 0))                     (xr_line)                  yt_line in range(0,146,4):                     clrt = int(yt_line * 1.7)                     img_load.putpixel((199, yt_line), (clrt, 0, 0))                     img_load.putpixel((200, yt_line), (clrt, clrt,  clrt))                     img_load.putpixel((201, yt_line), (clrt, 0, 0))                     (yt_line)                  yb_line in range(158,300,4):                     clrb = int((300 - yb_line) * 1.7)                     img_load.putpixel((199, yb_line), (clrb, 0, 0))                     img_load.putpixel((200, yb_line), (clrb, clrb, clrb))                     img_load.putpixel((201, yb_line), (clrb, 0, 0))                     (yb_line)                   img_render = imagetk.photoimage(img_load)                  # labels can text or images                 img = label(self, image=img_render)                 img.image = img_render                 img.place(x=0, y=0)                 self.update_idletasks()                 img_stream.seek(0)                 img_stream.truncate(0)                  # tried these: ##                img_stream.flush() ##                print("flushed ", img_stream) ##                print("2nd ",img_stream) ##                del img_load  ## ##             ##            rawcapture.truncate(0) ##              ##            rawcapture.seek(0) ##            rawcapture.truncate(0)  ##            del render ##            img.image = none ##            foregnd_image = none                  (xxx)             pass        def showtext(self):         text = label(self, text="hey there lookin!")         text.pack()       def client_exit(self):         self.trim_running_bool = false         exit()   # root window created. here, window, # can later have windows within windows. root = tk()  root.geometry("400x300")  #creation of instance app = window(root)   #mainloop  root.mainloop()   

each time through loop creating new image object , new label, other objects. memory leak, since never destroy old image or old label.

generally speaking, should create 1 label, use the_label.configure(image=the_image) every time through loop. that, don't need create new labels or call place on it.

even better, since label automatically updates when associated image changes, need change the bits in image object , label should update automatically.

the simplest solution move image creation function of objects creating local objects can automatically garbage collected when function returns.

the first step create single label , single image in main thread:

class window(frame):     def __init__(self, master=none):         ...         self.image = photoimage(width=400, height=300)         self.label = label(self, image=self.image)         ... 

next, create function copies new data image. unfortunately, tkinter's implementation of copy method doesn't support full power of underlying image object. workaround described here: http://tkinter.unpythonic.net/wiki/photoimage#copy_a_subimage.

note: workaround example general purpose workaround uses more arguments need. in following example can omit many of arguments. documentation underlying tk photo object copy method here: http://tcl.tk/man/tcl8.5/tkcmd/photo.htm#m17

the implementation (i'm guessing; don't have way test it):

def new_image(self):     # code create new image goes here...     ...     img_render = imagetk.photoimage(img_load)      # copy new image bits existing image object     self.tk.call(self.image, 'copy', img_render) 

finally, loop update image simpler:

while true:     self.new_image()     # presumeably there's sort of sleep here you're     # not updating image faster camera can      # capture it. 

i don't know how fast new_image can run. if can run in 200ms or less don't need threads. instead, can use after run function periodically.


note: haven't worked tkinter photo images in long time, , have no way test this. use guide, rather definitive solution.


Comments

Popular posts from this blog

sublimetext3 - what keyboard shortcut is to comment/uncomment for this script tag in sublime -

java - No use of nillable="0" in SOAP Webservice -

ubuntu - Laravel 5.2 quickstart guide gives Not Found Error -