PAYATHON 2026

如何让 MediaPipe FaceDetector 检测摄像头中的人脸?

数据小许

代码打开了摄像头并显示画面,但没有将视频帧传给 FaceDetector。在 LIVE_STREAM 模式下,每读取一帧都要调用 detector.detect_async()。调用前还要将 OpenCV 的 BGR 图像转换为 RGB,并封装成 mp.Image。

修改摄像头循环

下面的示例沿用 LIVE_STREAM 和 result_callback。请确认 model_asset_path 指向实际存在的 .tflite 模型文件。

import time
import cv2 as cv
import mediapipe as mp

BaseOptions = mp.tasks.BaseOptions
FaceDetector = mp.tasks.vision.FaceDetector
FaceDetectorOptions = mp.tasks.vision.FaceDetectorOptions
FaceDetectorResult = mp.tasks.vision.FaceDetectorResult
VisionRunningMode = mp.tasks.vision.RunningMode


def print_result(
    result: FaceDetectorResult,
    output_image: mp.Image,
    timestamp_ms: int,
):
    print(f"face detector result: {result}")


options = FaceDetectorOptions(
    base_options=BaseOptions(
        model_asset_path=r"C:\Users\hugop\Documents\python\face_project\blaze_face_short_range.tflite"
    ),
    running_mode=VisionRunningMode.LIVE_STREAM,
    result_callback=print_result,
)

cap = cv.VideoCapture(0)
if not cap.isOpened():
    raise RuntimeError("无法打开摄像头")

try:
    with FaceDetector.create_from_options(options) as detector:
        while True:
            ret, frame = cap.read()
            if not ret:
                print("无法读取视频帧,退出。")
                break

            # OpenCV 读取的是 BGR;MediaPipe 图像使用 RGB。
            rgb_frame = cv.cvtColor(frame, cv.COLOR_BGR2RGB)
            mp_image = mp.Image(
                image_format=mp.ImageFormat.SRGB,
                data=rgb_frame,
            )

            # LIVE_STREAM 要求时间戳以毫秒为单位,并随帧递增。
            timestamp_ms = time.monotonic_ns() // 1_000_000
            detector.detect_async(mp_image, timestamp_ms)

            cv.imshow("Camera", frame)
            if cv.waitKey(1) == ord("q"):
                break
finally:
    cap.release()
    cv.destroyAllWindows()

原代码为何没有检测结果

原代码创建了 FaceDetector,也读取并显示了摄像头画面,但循环中没有调用检测方法。因此,result_callback 没有收到检测结果。detect_async() 会将每帧提交给异步检测流程,检测完成后再调用 print_result。

传给检测器的图像也要符合 MediaPipe 的格式要求。OpenCV 通常使用 BGR 通道顺序,所以示例先用 cv.cvtColor 将图像转为 RGB,再通过 mp.ImageFormat.SRGB 创建 mp.Image。异步调用还需要毫秒时间戳。示例使用单调时钟生成递增时间戳,避免系统时钟调整导致时间戳倒退。

检查事项

  • 确认模型文件路径有效,且当前 Python 进程有权限读取该文件。
  • 确认摄像头索引 0 对应预期设备。设备不可用时,可尝试系统提供的其他摄像头索引。
  • 检测结果通过回调异步返回,提交帧后不一定会立即打印。画面能显示只说明视频流读取成功,不能证明检测器已处理图像。
  • 如果安装的 MediaPipe 版本不支持示例中的 Tasks API 或参数形式,请参考该版本对应的 API。

备注:内容仅供参考。