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

如何在OpenCV人脸距离测量程序中实现检测时长判定功能

人脸距离测量程序优化:延迟10秒显示过近/过远提示

原程序基于OpenCV实现人脸距离检测,当距离小于50cm时直接显示"Too Close",大于100cm时显示"Too Far"。需要优化为仅当用户持续处于过近/过远状态超过10秒时,才显示对应的提示信息。

优化后的完整代码

import cv2
import cvzone
import time
from cvzone.FaceMeshModule import FaceMeshDetector
from plyer import notification

cap = cv2.VideoCapture(0)
detector = FaceMeshDetector(maxFaces=1)  # 仅检测一张人脸

# 时间跟踪变量
start_time = None
current_state = "normal"  # 可选状态:normal/too_close/too_far
THRESHOLD_TIME = 10  # 触发提示的持续时间(秒)

while True:
    success, img = cap.read()
    img, faces = detector.findFaceMesh(img, draw=False)

    if faces:
        face = faces[0]
        pointLeft = face[145]
        pointRight = face[374]

        w, _ = detector.findDistance(pointLeft, pointRight)  # 像素宽度
        W = 6.3  # 双眼平均间距(cm)
        f = 642  # 预先计算的焦距
        d = (W * f) / w  # 计算实际距离
        print(f"当前距离:{d:.1f}cm")

        # 判断当前状态
        new_state = "normal"
        if d < 50:
            new_state = "too_close"
        elif d > 100:
            new_state = "too_far"

        # 状态变化处理
        if new_state != current_state:
            current_state = new_state
            start_time = time.time()  # 重置计时起点
        else:
            # 计算持续时间
            elapsed_time = time.time() - start_time
            # 超过阈值才显示提示
            if elapsed_time >= THRESHOLD_TIME:
                if current_state == "too_close":
                    cvzone.putTextRect(img, f'Too Close',
                                      (face[10][0] - 100, face[10][1] - 50),
                                      scale=2)
                    # 可选:触发系统通知
                    # notification.notify(
                    #     title='人脸距离提醒',
                    #     message='距离过近!',
                    #     app_icon=None,
                    #     timeout=2,
                    # )
                elif current_state == "too_far":
                    cvzone.putTextRect(img, f'Too Far',
                                      (face[10][0] - 100, face[10][1] - 50),
                                      scale=2)
                    # 可选:触发系统通知
                    # notification.notify(
                    #     title='人脸距离提醒',
                    #     message='距离过远!',
                    #     app_icon=None,
                    #     timeout=2,
                    # )
                else:
                    cvzone.putTextRect(img, f'Distance: {int(d)}cm',
                                      (face[10][0] - 100, face[10][1] - 50),
                                      scale=2)
            else:
                # 未超过阈值时显示当前距离
                cvzone.putTextRect(img, f'Distance: {int(d)}cm',
                                  (face[10][0] - 100, face[10][1] - 50),
                                  scale=2)
    else:
        # 未检测到人脸时重置状态
        current_state = "normal"
        start_time = None

    cv2.imshow("Image", img)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

关键改动说明

  • 引入time模块实现时间跟踪,新增三个核心变量:start_time记录状态起始时间,current_state标记当前距离状态,THRESHOLD_TIME设置10秒的触发阈值。
  • 每次检测距离后先判断新状态,若状态变更则重置计时;若状态持续,计算已持续时长,仅当超过10秒时才显示提示。
  • 未检测到人脸时自动重置状态,避免因人脸暂时消失导致的误触发。
  • 补充了摄像头资源释放和窗口关闭的逻辑,优化程序完整性。

内容的提问来源于stack exchange,提问作者M N Perera

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 11:22:46