Warning: It's ugly due to a Tkinter/multiprocessing bug in Linux/Mac.
http://bugs.python.org/issue5527#msg195480
import cv2 import multiprocessing def cam_loop(the_q, event): width, height = 800, 600 cap = cv2.VideoCapture(0) cap.set(cv2.CAP_PROP_FRAME_WIDTH, width) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height) while True: _ , img = cap.read() if img is not None: img = cv2.flip(img, 1) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGBA) the_q.put(img) event.set() if __name__ == '__main__': try: logger = multiprocessing.log_to_stderr() logger.setLevel(multiprocessing.SUBDEBUG) the_q = multiprocessing.Queue(1) event = multiprocessing.Event() cam_process = multiprocessing.Process(target=cam_loop,args=(the_q, event)) cam_process.start() # Bug in Tkinter, must be imported after processes are forked: import Tkinter as tk from PIL import Image, ImageTk class TkGui(tk.Tk): def __init__(self): tk.Tk.__init__(self, None) self.parent = None self.bind('', lambda e: self.quit()) self.lmain = tk.Label(self) self.lmain.pack() def update_frame(self, img): img = Image.fromarray(img) imgtk = ImageTk.PhotoImage(image=img) self.lmain.imgtk = imgtk self.lmain.configure(image=imgtk) self.update() def gui_mainloop(the_q, event): gui = TkGui() while True: event.wait() img = the_q.get() gui.update_frame(img) gui_mainloop(the_q, event) cam_process.join() except KeyboardInterrupt: cam_process.terminate()
The idea is to have a camera-capture process running in parallel to the gui one.
So, the "cam_loop" method is transformed into a separate process (#27), images are captured from the webcam in a loop, a bit of make-up for them(#13-14), puts one of them into a queue, and sends a signal to the event saying: hey! there is something here.
At the same time, the main process has been importing the gui, creates a simple Tkinter root, enters in a hand made "mainloop", and awaits for the signal from the cam_process(#53). Once it receives it, tells the gui to update, so it shows the new image received.
The events are not really needed, but they seem to be a nice way of not wasting cycles in the gui loop, that is, only refresh when there is a frame waiting.
Goods news is that CPU usage is less than previous tests, around 55-60%:
No comments:
Post a Comment