You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python while循环内如何实现函数调用仅一次,间隔5秒再触发且不阻塞循环

解决方案

核心是给触发逻辑加5秒冷却校验,全程不会阻塞主线程的视频流处理逻辑:

  1. 新增变量记录上一次成功触发play_save的时间
  2. 每次检测到笑脸时,先校验当前时间与上一次触发时间的间隔是否达到5秒,只有满足间隔要求才启动新线程执行保存和播放逻辑,同时更新上次触发时间

修改后的完整代码

import cv2
import datetime
import threading
import time
from playsound import playsound

def play_save(save_img):
    print("Saving Image")
    time_stamp = datetime.datetime.now().strftime('%Y-%m-%d-%H-%M-%S')
    file_name = f'selfie-{time_stamp}.png'
    cv2.imwrite(file_name, save_img)
    print("Playing Song")
    playsound("Happy_birthday.mp3")

def main():
    face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
    smile_cascade = cv2.CascadeClassifier('haarcascade_smile.xml')
    cap = cv2.VideoCapture(0)
    # 新增:记录上一次触发的时间,初始值设为5秒前保证首次检测到笑脸可以直接触发
    last_trigger_time = datetime.datetime.now() - datetime.timedelta(seconds=5)
    COOLDOWN_SECONDS = 5

    while True:
        ret, img = cap.read()
        frame = img.copy()
        if not ret:
            break
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        faces = face_cascade.detectMultiScale(gray, 1.3, 5)
        for (x, y, w, h) in faces:
            cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)
            roi_gray = gray[y:y + h, x:x + w]
            roi_color = img[y:y + h, x:x + w]
            smile = smile_cascade.detectMultiScale(roi_gray, 1.3, 25)
            for x1, y1, w1, h1 in smile:
                cv2.rectangle(img, (x1, y1), (x1 + w1, y1 + h1), (0, 0, 255), 2)
                # 新增:冷却校验逻辑
                current_time = datetime.datetime.now()
                if (current_time - last_trigger_time).total_seconds() >= COOLDOWN_SECONDS:
                    multithread = threading.Thread(target=play_save, args=(frame,))
                    multithread.start()
                    # 更新触发时间
                    last_trigger_time = current_time

        cv2.imshow('Smile Birthday', img)
        k = cv2.waitKey(30) & 0xff
        if k == 27:
            break

    cap.release()
    cv2.destroyAllWindows()

if __name__ == "__main__":
    main()

方案说明

  • 时间差判断逻辑只有简单的数值计算,耗时可以忽略,完全不会阻塞while循环的帧读取、渲染流程,视频画面不会出现卡顿
  • 冷却期内所有检测到的笑脸触发请求都会被直接跳过,不会重复启动线程,避免了歌曲重叠、重复存图的问题
  • 冷却时长可以通过修改COOLDOWN_SECONDS变量灵活调整

内容的提问来源于stack exchange,提问作者git-ruthvik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 12:09:01