1 import tkinter as tk 2 from PIL import Image, ImageTk 3 import cv2 4 import numpy as np 5 import time 6 7 g_exit = False 8 9 def close_window(): 10 global g_exit 11 g_exit = True 12 13 def video_init(): 14 cap = cv2.VideoCapture(0) 15 cap.set(3, 640) 16 cap.set(4, 480) 17 time.sleep(2) 18 return cap 19 20 def video_show(): 21 cap = video_init() 22 while (cap.isOpened() and g_exit == False): 23 ret, frame = cap.read() 24 if ret == True: 25 frame = cv2.flip(frame, 1) 26 # 将图像的通道顺序由BGR转换成RGB 27 frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) 28 if isinstance(frame, np.ndarray): 29 frame = Image.fromarray(frame.astype(np.uint8)) 30 31 photo = ImageTk.PhotoImage(image=frame) 32 image_cvs.create_image([320, 240], image=photo) 33 34 win.update_idletasks() 35 win.update() 36 cap.release() 37 win.quit() 38 39 if __name__ == '__main__': 40 win = tk.Tk() 41 image_cvs = tk.Canvas(win, width=640, height=480, bg='white') 42 image_cvs.pack() 43 44 # 点击界面右上角的关闭按钮时,会触发'WM_DELETE_WINDOW'消息 45 # 我们在此截获该消息,并改变其行为 46 win.protocol('WM_DELETE_WINDOW', close_window) 47 48 win.after(200, video_show) 49 win.mainloop()
在使用Canvas显式图片时,其image参数有两个重要的点需要注意,一个是格式,另外一个是要保持持续引用(可使用全局变量)。如下:
- The image object should be a PhotoImage or BitmapImage, or a compatible object (such as the PIL PhotoImage).
- The application must keep a reference to the image object.