通过处理这个multiprocessing
比你想象的更容易:
import multiprocessing
import Tkinter as tk
import cv2
e = multiprocessing.Event()
p = None
# -------begin capturing and saving video
def startrecording(e):
cap = cv2.VideoCapture(0)
fourcc = cv2.cv.CV_FOURCC(*'XVID')
out = cv2.VideoWriter('output.avi',fourcc, 20.0, (640,480))
while(cap.isOpened()):
if e.is_set():
cap.release()
out.release()
cv2.destroyAllWindows()
e.clear()
ret, frame = cap.read()
if ret==True:
out.write(frame)
else:
break
def start_recording_proc():
global p
p = multiprocessing.Process(target=startrecording, args=(e,))
p.start()
# -------end video capture and stop tk
def stoprecording():
e.set()
p.join()
root.quit()
root.destroy()
if __name__ == "__main__":
# -------configure window
root = tk.Tk()
root.geometry("%dx%d+0+0" % (100, 100))
startbutton=tk.Button(root,width=10,height=1,text='START',command=start_recording_proc)
stopbutton=tk.Button(root,width=10,height=1,text='STOP', command=stoprecording)
startbutton.pack()
stopbutton.pack()
# -------begin
root.mainloop()
我们所做的就是添加一个调用multiprocessing.Process https://docs.python.org/2/library/multiprocessing.html#the-process-class以便您的视频捕获代码在子进程中运行,并在捕获完成时将代码移动到该进程中进行清理。与单进程版本相比,唯一的额外问题是使用multiprocessing.Event https://docs.python.org/2/library/multiprocessing.html#multiprocessing.Event当需要关闭时向子进程发出信号,这是必要的,因为父进程无权访问out
or cap
.
你可以尝试使用threading
相反(只需替换multiprocessing.Process
with threading.Thread
, and multiprocessing.Event
with threading.Event
),但我怀疑 GIL 会绊倒你并损害 GUI 线程的性能。出于同样的原因,我认为不值得尝试通过以下方式将读/写流集成到事件循环中root.after
- 它只会损害性能,并且由于您不尝试将所做的事情集成到 GUI 本身中,因此没有理由尝试将其保留在与事件循环相同的线程/进程中。