我正在尝试开发一个代码,通过该代码我可以访问网络摄像头并在Tkinter窗口中显示视频。我已经能够访问网络摄像头,加载视频,甚至使用参考代码Tkinter nested mainloop停止视频
我想要的还有一个“点击”按钮,该按钮可以捕捉当时的视频帧并显示捕获的帧。此外,应保持代码按下加载按钮并重新加载视频帧的能力。
目前我正在使用此代码 -
from multiprocessing import Process, Queue
import cv2
import ImageTk
from PIL import *
import Image
import Tkinter as tk
def image_capture(queue):
vidFile = cv2.VideoCapture(0)
while True:
flag, frame=vidFile.read()
frame = cv2.cvtColor(frame,cv2.cv.CV_BGR2RGB)
queue.put(frame)
cv2.waitKey(10)
def update_all(root, imagelabel, queue, process, var):
if var.get()==True:
global im
im = queue.get()
a = Image.fromarray(im)
b = ImageTk.PhotoImage(image=a)
imagelabel.configure(image=b)
imagelabel._image_cache = b
root.update()
root.after(0, func=lambda: update_all(root, imagelabel, queue, process, var))
else:
print var.get()
root.quit()
def playvideo(root, imagelabel, queue, var):
global im
p = Process(target=image_capture, args=(task,))
p.start()
update_all(root, imagelabel, queue, p, var)
root.mainloop()
p.terminate()
if var.get()==False:
try:
cv2.imwrite("capturedFrame.jpg",im[:, :, ::-1])
a = Image.fromarray(im)
imagelabel.configure(image=a)
imagelabel._image_cache = im
except Exception,e:
print e
var.set(True)
print 'finishing'
if __name__ == '__main__':
try:
task = Queue()
root = tk.Tk()
image_label = tk.Label(master=root)
image_label.grid(column=0, row=0, columnspan=2, rowspan=1)
background = ImageTk.PhotoImage(file='img.jpg')
image_label['image'] = background
button_frame = tk.Frame(root)
button_frame.grid(column=0, row=1, columnspan=1)
load_button = tk.Button(master=button_frame, text='Load video',command=lambda: playvideo(root, image_label, task, switch))
load_button.grid(column=0, row=0, sticky='ew')
#Click button
switch = tk.BooleanVar(master=root, value=True, name='switch')
stop_button = tk.Button(master=button_frame, text='Click',command=lambda: switch.set(False))
stop_button.grid(column=0, row=1, sticky='ew')
#quit button
quit_button = tk.Button(master=button_frame, text='Quit',command=root.destroy)
quit_button.grid(column=0, row=2, sticky='ew')
root.mainloop()
except Exception,e:
print e
此代码单击单击按钮上的图像,甚至保存图像,但抛出异常 -
image "<Image.Image image mode=RGB size=640x480 at 0x5494FA8>" doesn't exist
虽然代码有效,但有没有更好的方法从网络摄像头点击并保存这些点击的图像。任何形式的帮助将不胜感激。谢谢。
答案 0 :(得分:0)
要从相机保存当前帧并保持流式传输,您应该将单击按钮操作与独立功能关联,让我们按如下方式调用saveImage(队列):
def saveImage(queue):
img = queue.get()
cv2.imwrite("capturedFrame.jpg",img)
,单击按钮可以声明如下:
click_button = tk.Button(master=button_frame, text='Click',command=lambda: saveImage(task))
其中'task'是您在main函数中启动的队列。