使用 Tkinter 拍摄一些 Gif 后网络摄像头预览滞后

问题描述 投票:0回答:1

我正在创建用于拍摄 gif 的程序,虽然在拍摄 5-6 张 gif 后一切都按预期进行,但网络摄像头预览开始滞后,整个程序也开始滞后。

网络摄像头预览.py

class WebcamPreview:
def __init__(self, preview_size=(960, 540)):
    self.cam = cv2.VideoCapture(cv2.CAP_DSHOW)
    self.preview_size = preview_size
    self.frame = None
    self.image = None
    self.running = False

def start_preview(self, label):
    self.running = True
    threading.Thread(target=self._update_preview, args=(label,), daemon=False).start()

def _update_preview(self, label):
    while self.running:
        ret, frame = self.cam.read()
        if ret:
            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            frame = cv2.resize(frame, self.preview_size)
            self.frame = frame
            self.image = ImageTk.PhotoImage(Image.fromarray(frame))
            label.config(image=self.image)
            label.image = self.image  # Keep a reference
            time.sleep(0.03)  # Adjust the sleep time to control frame rate

def capture_image(self, filename):
    if self.frame is not None:
        cv2.imwrite(filename, cv2.cvtColor(self.frame, cv2.COLOR_RGB2BGR))

def capture_Gif(self, duration, filename):
    frames = []
    start_time = time.time()
    while time.time() - start_time < duration:
        ret, frame = self.cam.read()
        if ret:
            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            frame = cv2.resize(frame, self.preview_size)
            frames.append(frame)
            time.sleep(0.1)  # Adjust the sleep time to control frame rate

    # Convert frames to GIF
    imageio.mimsave(filename, frames, duration=0.03)

def capture_video(self):

    video_frames = self.capture_video_frames()
    if video_frames:
        self.save_video(video_frames)

def capture_video_frames(self):
    video_frames = []
    num_frames = int(30 * 5)  # Capture 30 frames per second for 5 seconds
    for _ in range(num_frames):
        ret, frame = self.cam.read()  # Capture a frame from the webcam
        if ret:
            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            frame = cv2.resize(frame, (960, 540))
            video_frames.append(frame)
    return video_frames

def save_video(self, frames):
    out = cv2.VideoWriter("Assets/temp_video.avi", cv2.VideoWriter_fourcc(*'DIVX'), 30, (960, 540))
    for frame in frames:
        out.write(frame)
    out.release()

def stop_preview(self):
    self.running = False
    self.cam.release()

捕获页面.py

class CapturePage(tk.Frame):
def __init__(self, parent, controller):
    tk.Frame.__init__(self, parent)
    self.controller = controller
    self.thread_stop_event = Event()
    
    self['bg']='#DEF7E5'

    self.back_button = tk.Button(self, text="◀ Back",  font=("Arbutus Slab", 10), command=lambda:    controller.show_frame("DefaultPage"), 
                                 background='#DEF7E5', activebackground='#DEF7E5', bd=0)
    self.back_button.place(x=40, y=40)
    
    self.webcam_preview = WebcamPreview()

    self.preview_label = tk.Label(self)
    self.preview_label.pack(pady=60)


    self.image = PhotoImage(file="Assets/Capture_button.png")

    button = tk.Button(self, image=self.image, borderwidth=0, relief="flat",       highlightthickness=0, background='#DEF7E5', command=self.capture)
    button.pack() 
    
    self.White_square = tk.Label(self, bg="white")
    self.transparent_black_square = tk.Label(self, bg="black")
    self.processing_label = tk.Label(self.transparent_black_square, text="Processing...", fg="white", font=("Arial", 16))

    

def capture(self):
    format = self.controller.format_global
    if format == "Image":
        self.capture_image()
    elif format == "GIF":
        self.capture_gif()
    elif format == "Video":
        self.capture_video()

def capture_image(self):
    self.webcam_preview.capture_image("Assets/Temp_image.jpg")
    self.controller.show_frame("CheckMedia")

def capture_gif(self):
    gifCapture = Thread(target=self.gif_thread)
    gifCapture.start()
    self.Light()
    self.after(5000, self.turn_off_light)
    self.after(5000, self.Proccesing)

def gif_thread(self):
    self.thread_stop_event.clear()  # Reset the flag before capture
    while not self.thread_stop_event.is_set():
        self.webcam_preview.capture_Gif(5, "Assets/Temp_gif.gif")
        if not self.thread_stop_event.is_set():
            self.controller.show_frame("CheckMedia")
        else:
            # Clean up resources if needed
            break

def capture_video(self):
    videoCapture = Thread(target=self.Video_thread)
    videoCapture.start()
    self.Light()
    self.after(5000, self.turn_off_light)
    self.after(5000, self.Proccesing)

def Video_thread(self):
    self.thread_stop_event.clear()  # Reset the flag before capture
    while not self.thread_stop_event.is_set():
        self.webcam_preview.capture_video()
        if not self.thread_stop_event.is_set():
            self.controller.show_frame("CheckMedia")
        else:
            # Clean up resources if needed
            break

def Light(self):
    self.White_square.place(x=0, y=0, relwidth=1, relheight=1)

def turn_off_light(self):
    self.White_square.place_forget()

def Proccesing(self):
    self.transparent_black_square.place(x=0, y=0, relwidth=1, relheight=1)
    self.processing_label.place(relx=0.5, rely=0.5, anchor="center")

def on_show_frame(self):
    self.webcam_preview.start_preview(self.preview_label)

def on_hide_frame(self):
    self.White_square.place_forget()
    self.transparent_black_square.place_forget()
    self.processing_label.place_forget() 
    self.thread_stop_event.set()`

我需要编程顺利,但我在网上找不到任何答案,这是我最后的选择。我尝试过更改线程之类的东西,但没有任何效果。

python multithreading opencv tkinter
1个回答
0
投票

您的服务器会滞后,因为您创建了一个新线程来处理每个新的 gif/视频。

您应该看到每次运行代码时使用了多少内存。

© www.soinside.com 2019 - 2024. All rights reserved.