user interface - how to replace an ongoing process of image capture from another process call over the same ImageLabel in python's GUI TKinter -


i trying use following code create interactive gui changes color-space(hsv, rbg, grayscale etc) on event of button click. display opencv video in tkinter using multiprocessing being new python having problems multiprocessing , attempts on making gui change it's color space on button clicks hangs entire system. on it's implementation highly appreciated. thankyou. below code:

import cv2 pil import image,imagetk import tkinter tk import numpy np multiprocessing import process , queue  def quit_it(root,process):     root.destroy()     process.terminate()  def black_andwhite(root,process):     process.terminate     p=process(target=capture_image, args=(5,queue, ))     p.start()     root.after(0, func=lambda: update_all(root, image_label, queue))  def update_image(image_label, queue):     frame = queue.get()     = image.fromarray(frame)     b = imagetk.photoimage(image=a)     image_label.configure(image=b)     image_label._image_cache = b     root.update()  def update_all(root, image_label, queue):     update_image(image_label, queue)     root.after(0, func=lambda: update_all(root, image_label, queue))  def capture_image(var,queue):     vidfile = cv2.videocapture(0)     while true:        try:           flag, frame=vidfile.read()           if flag==0:              break           if(var==5):              frame1=cv2.cvtcolor(frame, cv2.color_bgr2gray)           else:              frame1=cv2.cvtcolor(frame, cv2.color_bgr2rgb)           queue.put(frame1)           cv2.waitkey(20)        except:           continue   if __name__ == '__main__':     queue=queue();     root=tk.tk()     root.geometry("1500x1200+2+2")     image_label=tk.label(master=root)     image_label.pack()     p=process(target=capture_image, args=(7,queue, ))     p.start()      quit_button=tk.button(master=root, text='quit', command=lambda:quit_it(root,p))     quit_button.pack()      bandw_button=tk.button(master=root, text='black_and_white',command=lambda:black_andwhite(root,p))     bandw_button.pack()      root.after(5, func=lambda: update_all(root, image_label, queue,))     root.mainloop()     p.terminate() 

add logging code see parts executed when. multithreaded code hard debug (because things happen while debugger waits you). logging give report of happened when , allow track down unexpected behavior.$

in case, see 2 problems:

except: continue 

will silently ignore problems in frame capture loop. if goes wrong, no image pushed queue. should cause queue.get() throw empty exception.

the second problem install update_all() twice. have 1 process/loop adds 1 image per n milliseconds queue 2 callbacks in main event loop try image. cause python lock up.

again, use logging see when processes started, when images put queue , taken , how many callbacks registered process images in queue.

[edit] if original code works, use different approach:

instead of installing second callback after() set flag. when flag set, change colorspace. otherwise, leave alone. when button clicked, toggle flag.


Comments

Popular posts from this blog

Rendering JButton to get the JCheckBox behavior in a JTable by using images does not update my table -

javascript - Using jquery append to add option values into a select element not working -

Android soft keyboard reverts to default keyboard on orientation change -