如何在Tkinter Canvas中显示摄像头画面?代码问题求助
问题描述
我开发了一个基于Tkinter和CustomTkinter的GUI,其中Canvas默认显示一张图片,且设有一个开关,切换时会打印Cam On或Cam off。我期望打开该开关时,用摄像头实时流替换默认图片。
我找到了一段可在独立Canvas中实现摄像头画面显示的代码,但无法将其逻辑整合到我的GUI代码中。
尝试合并代码后,切换开关时摄像头已启动(硬件指示灯亮起、系统弹出程序启动摄像头的通知),但画面并未显示在Canvas上,恳请帮忙排查并解决该问题。
原始GUI代码
import tkinter import tkinter.messagebox import customtkinter from PIL import Image,ImageTk # Setting up theme of GUI customtkinter.set_appearance_mode("Dark") # Modes: "System" (standard), "Dark", "Light" customtkinter.set_default_color_theme("blue") # Themes: "blue" (standard), "green", "dark-blue" class App(customtkinter.CTk): def __init__(self): super().__init__() # configure window self.is_on = True self.image = ImageTk.PhotoImage(Image.open("../data/Mars.PNG")) self.title("Cool Blue") self.geometry(f"{1200}x{635}") # configure grid layout (4x4) self.grid_columnconfigure(1, weight=1) self.grid_columnconfigure((2, 3), weight=0) self.grid_rowconfigure((0, 1, 2, 3), weight=0) ################################################################### # Create Sidebar for LED, LIghts and Camera controls ################################################################### self.lights_control = customtkinter.CTkFrame(self) self.lights_control.grid(row=3, column=0, rowspan = 1, padx=(5, 5), pady=(10, 10), sticky="nsew") self.lights_control.grid_rowconfigure(1, weight=1) # Camera self.camera_switch = customtkinter.CTkSwitch(master=self.lights_control, text="Camera", command=self.camera_switch) self.camera_switch.grid(row=2, column=1, pady=10, padx=20, ) ################################################################### # Create canvas for RPCam live stream ################################################################### self.picam_frame = customtkinter.CTkFrame(self) self.picam_frame.grid(row=0, column=1, rowspan=4, padx=(5, 5), pady=(10, 10), sticky="nsew") self.picam_frame.grid_rowconfigure(4, weight=1) self.picam_canvas = customtkinter.CTkCanvas(self.picam_frame, width=1730, height=944, background="gray") self.picam_canvas.create_image(0, 0, image=self.image, anchor="nw") self.picam_canvas.pack() ######################################################################### # Camera Switch ######################################################################### def camera_switch(self, event=None): if self.is_on: print("Cam on") self.is_on = False else: print("Cam off") self.is_on = True if __name__ == "__main__": app = App() app.mainloop()
参考代码
# Import required Libraries from tkinter import * from PIL import Image, ImageTk import cv2 # Create an instance of TKinter Window or frame win = Tk() # Set the size of the window win.geometry("700x350") # Create a Label to capture the Video frames label =Label(win) label.grid(row=0, column=0) cap= cv2.VideoCapture(0) # Define function to show frame def show_frames(): # Get the latest frame and convert into Image cv2image= cv2.cvtColor(cap.read()[1],cv2.COLOR_BGR2RGB) img = Image.fromarray(cv2image) # Convert image to PhotoImage imgtk = ImageTk.PhotoImage(image = img) label.imgtk = imgtk label.configure(image=imgtk) # Repeat after an interval to capture continiously label.after(20, show_frames) show_frames() win.mainloop()
尝试后的代码
import tkinter import tkinter.messagebox import customtkinter from PIL import Image,ImageTk import cv2 # Setting up theme of GUI customtkinter.set_appearance_mode("Dark") # Modes: "System" (standard), "Dark", "Light" customtkinter.set_default_color_theme("blue") # Themes: "blue" (standard), "green", "dark-blue" class App(customtkinter.CTk): def __init__(self): super().__init__() # configure window self.is_on = True self.image = ImageTk.PhotoImage(Image.open("../data/Mars.PNG")) self.capture = cv2.VideoCapture(0) self.title("Cool Blue") self.geometry(f"{1200}x{635}") # configure grid layout (4x4) self.grid_columnconfigure(1, weight=1) self.grid_columnconfigure((2, 3), weight=0) self.grid_rowconfigure((0, 1, 2, 3), weight=0) ################################################################### # Create Sidebar for LED, LIghts and Camera controls ################################################################### self.lights_control = customtkinter.CTkFrame(self) self.lights_control.grid(row=3, column=0, rowspan = 1, padx=(5, 5), pady=(10, 10), sticky="nsew") self.lights_control.grid_rowconfigure(1, weight=1) # Camera self.camera_switch = customtkinter.CTkSwitch(master=self.lights_control, text="Camera", command=self.camera_switch) self.camera_switch.grid(row=2, column=1, pady=10, padx=20, ) ################################################################### # Create canvas for RPCam live stream ################################################################### self.picam_frame = customtkinter.CTkFrame(self) self.picam_frame.grid(row=0, column=1, rowspan=4, padx=(5, 5), pady=(10, 10), sticky="nsew") self.picam_frame.grid_rowconfigure(4, weight=1) # self.picam_canvas = customtkinter.CTkCanvas(self.picam_frame, width=1730, height=944, background="gray") # self.picam_canvas.create_image(0, 0, image=self.image, anchor="nw") self.picam_canvas = tkinter.Canvas(self.picam_frame, width=1730, height=944) #self.picam_canvas.pack ######################################################################### # Camera Switch ######################################################################### def camera_switch(self, event=None): if self.is_on: self.update_frames() print("Cam on") self.is_on = False else: #self.close_camera() self.image print("Cam off") self.is_on = True def update_frames(self): # Get the current frame from the webcam _, frame = self.capture.read() # Convert the frame to a PhotoImage object frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) frame = Image.fromarray(frame) frame = ImageTk.PhotoImage(frame) # Update the canvas with the new frame self.picam_canvas.create_image(0, 0, image=frame, anchor="nw") self.picam_canvas.image = frame # Schedule the next update self.after(1000, self.update_frames) def close_camera(self): self.capture.release() if __name__ == "__main__": app = App() app.mainloop()
内容的提问来源于stack exchange,提问作者Slavisha84
相关产品推荐
相关产品推荐

