我正在创建用于拍摄 gif 的程序,虽然在拍摄 5-6 张 gif 后一切都按预期进行,但网络摄像头预览开始滞后,整个程序也开始滞后。
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()
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()`
我需要编程顺利,但我在网上找不到任何答案,这是我最后的选择。我尝试过更改线程之类的东西,但没有任何效果。
您的服务器会滞后,因为您创建了一个新线程来处理每个新的 gif/视频。
您应该看到每次运行代码时使用了多少内存。