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

PyQt5树莓派4平台实现每第N帧执行人脸检测其余帧仅显示

帧计数跳帧检测实现方案

这种方式完全可行,比延时逻辑稳定得多,计数直接对应摄像头实际读取到的有效帧数量,不会因为摄像头帧率波动、人脸检测耗时导致间隔不准。

原有代码的问题

  • 计数步长错误:每成功读取1帧时,你给process_this_frame加了2,而非加1,导致计数数值和实际物理帧数完全不匹配。比如原本想每20帧检测一次,按当前步长实际每10帧就会触发一次检测;如果改成%30的取模条件,实际要间隔60个物理帧才会检测一次,完全不符合预期。
  • 没有可配置的间隔参数,后续调整检测频率需要改多处逻辑,不方便测试最优运行参数。

修正实现逻辑

  1. 定义独立的间隔常量FRAME_INTERVAL,后续调整检测频率只需要修改这一个值即可
  2. 每成功读取1帧,计数器累加1,不跳步
  3. 当计数器对间隔值取模等于0时,才执行人脸检测、标注逻辑
  4. 若你要求非检测帧直接展示原始画面,直接发送原始采集帧即可;如果希望人脸标注不会在跳过帧上闪烁消失,可以加变量缓存上一次的检测结果,非检测帧复用缓存结果叠加标注。

参考实现代码

严格符合“非检测帧展示原始画面”的需求版本

def run(self):
    # 可配置参数:每隔N帧执行一次人脸检测,调整频率直接改这个值即可
    FRAME_INTERVAL = 30
    # 有效帧计数器
    frame_count = 0
    # 初始化摄像头
    cap = cv2.VideoCapture(0)
    cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 300)
    
    while True:
        ret, cv_img = cap.read()
        if not ret:
            continue
        # 每成功读取1帧,计数器累加1
        frame_count += 1
        # 缩小帧用于检测,减少算力消耗(保留原有加速逻辑)
        img = cv2.resize(cv_img, (0, 0), fx=0.25, fy=0.25)
        
        # 仅在指定帧执行人脸检测
        if frame_count % FRAME_INTERVAL == 0:
            predictions = predict(img, model_path="trained_knn_model.clf")
            cv_img = show_prediction_labels_on_image(cv_img, predictions)
            print(f"第{frame_count}帧完成人脸检测")
        
        # 不管是否检测,都发射信号刷新界面
        self.change_pixmap_signal.emit(cv_img)

优化体验版(人脸标注不闪烁)

如果觉得非检测帧直接发原图会导致人脸框闪一下就消失,可以加缓存复用上次的检测结果:

def run(self):
    FRAME_INTERVAL = 30
    frame_count = 0
    # 缓存上一次的检测结果
    last_predictions = []
    cap = cv2.VideoCapture(0)
    cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 300)
    
    while True:
        ret, cv_img = cap.read()
        if not ret:
            continue
        frame_count += 1
        img = cv2.resize(cv_img, (0, 0), fx=0.25, fy=0.25)
        
        if frame_count % FRAME_INTERVAL == 0:
            last_predictions = predict(img, model_path="trained_knn_model.clf")
        
        # 用缓存的结果叠加标注,不管是否是检测帧
        if last_predictions:
            cv_img = show_prediction_labels_on_image(cv_img, last_predictions)
        
        self.change_pixmap_signal.emit(cv_img)

参数调整建议

  • 树莓派4算力有限,初始可以把FRAME_INTERVAL设为20~30,兼顾检测响应速度和画面流畅度
  • 如果检测响应太慢可以把间隔调到10~15,如果画面卡顿就再调大间隔数值

内容的提问来源于stack exchange,提问作者julius

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.24 17:45:03