[英]how to replace an ongoing process of image capture from another process call over the same ImageLabel in python's GUI TKinter
i am trying to use the following code to create an interactive GUI which changes the color-space(HSV, RBG, grayscale etc) on the event of button click. 我试图使用以下代码创建一个交互式GUI,以在单击按钮时更改颜色空间(HSV,RBG,灰度等)。 Display an OpenCV video in tkinter using multiprocessing Being new to python i am having problems with multiprocessing and my attempts on making the GUI which would change it's color space on button clicks hangs the entire system. 使用多重处理在tkinter中显示OpenCV视频对python来说是新手,我遇到了多重处理问题,我试图制作可改变按钮颜色空间的GUI挂在整个系统上。 Any help on it's implementation will be highly appreciated. 对其实施的任何帮助将不胜感激。 Thankyou. 谢谢。 Below is my code: 下面是我的代码:
import cv2
from PIL import Image,ImageTk
import Tkinter as tk
import numpy as np
from 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()
a = 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 some logging to the code to see which parts are executed when. 在代码中添加一些日志记录,以查看何时执行哪些部分。 Multithreaded code is always hard to debug (because things happen while the debugger waits for you). 多线程代码始终难以调试(因为调试器在等待您时会发生事情)。 Logging will give you a report of what happened when and that will allow you to track down unexpected behavior.$ 日志记录将为您提供有关何时何地发生的情况的报告,这将使您能够跟踪意外行为。
In this case, I see two problems: 在这种情况下,我看到两个问题:
except: continue
will silently ignore any problems in the frame capture loop. 将默默地忽略帧捕获循环中的任何问题。 So if something goes wrong, no image will be pushed to the queue. 因此,如果出现问题,则不会将任何图像推入队列。 But that should cause queue.get()
to throw an Empty
exception. 但这应该导致queue.get()
抛出Empty
异常。
The second problem is that you install update_all()
twice. 第二个问题是您安装两次update_all()
。 So you will have one process/loop which adds one image per N milliseconds to the queue but two callbacks in the main event loop that try to get an image. 因此,您将拥有一个进程/循环,该进程/循环每N毫秒将一幅图像添加到队列中,但是在主事件循环中有两个试图获取图像的回调。 That could cause Python to lock up. 这可能会导致Python锁定。
Again, use logging to see when processes are started, when images are put into the queue and taken from it and how many callbacks are registered to process images in the queue. 同样,使用日志记录来查看何时启动进程,何时将图像放入队列并从中获取图像,以及注册了多少回调以处理队列中的图像。
[EDIT] If the original code works, then use a different approach: [编辑]如果原始代码有效,则使用其他方法:
Instead of installing a second callback with after()
set a flag. 而不是使用after()
安装第二个回调,而是设置一个标志。 When the flag is set, change the colorspace. 设置标志后,更改色彩空间。 Otherwise, leave it alone. 否则,别管它。 When the button is clicked, toggle the flag. 单击按钮后,切换标志。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.