You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

OpenCV结合MediaPipe实现摄像头人脸检测失败问题求助

OpenCV结合MediaPipe实现摄像头人脸检测失败问题求助

看起来你已经搭好了基本的代码框架,但核心问题是你没有把摄像头捕获的帧传给MediaPipe的人脸检测器处理,而且缺少了格式转换和关键的检测调用步骤。我来帮你一步步修正代码,让它能正常检测并可视化人脸:

修改后的完整代码

import numpy as np
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

# 全局变量,用来传递检测结果给主循环(方便可视化)
detected_faces = None

def print_result(result: FaceDetectorResult, output_image: mp.Image, timestamp_ms: int):
    global detected_faces
    detected_faces = result
    # 可选:简化打印,只显示人脸数量
    print(f"检测到 {len(result.detections)} 张人脸")

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():
    print("Je ne peux pas ouvrir la caméra")
    exit()

# 初始化时间戳,LIVE_STREAM模式需要递增的时间戳标识帧顺序
timestamp = 0

with FaceDetector.create_from_options(options) as detector : 
    while True:
        ret, frame = cap.read()

        if not ret:
            print("Je ne peux pas recevoir le flux vidéo. Sortir...")
            break

        # 关键步骤1:OpenCV默认是BGR格式,MediaPipe需要RGB格式,先做颜色空间转换
        rgb_frame = cv.cvtColor(frame, cv.COLOR_BGR2RGB)
        # 关键步骤2:把转换后的RGB帧包装成MediaPipe能识别的mp.Image格式
        mp_image = mp.Image(image_format=mp.ImageFormat.SRGB, data=rgb_frame)
        # 关键步骤3:调用异步检测方法,传入图像和时间戳,触发回调函数
        detector.detect_async(mp_image, timestamp)
        timestamp += 1  # 时间戳必须持续递增,不能重复

        # 可选但实用:在原帧上绘制人脸检测框,直观看到结果
        if detected_faces is not None and len(detected_faces.detections) > 0:
            for detection in detected_faces.detections:
                # MediaPipe返回的是归一化坐标,需要转成当前帧的像素坐标
                bbox = detection.bounding_box
                x1 = int(bbox.origin_x * frame.shape[1])
                y1 = int(bbox.origin_y * frame.shape[0])
                x2 = int((bbox.origin_x + bbox.width) * frame.shape[1])
                y2 = int((bbox.origin_y + bbox.height) * frame.shape[0])
                # 画绿色矩形框和标签
                cv.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
                cv.putText(frame, "Face", (x1, y1-10), cv.FONT_HERSHEY_SIMPLEX, 0.9, (0,255,0), 2)

        cv.imshow('Caméra', frame)
        if cv.waitKey(1) == ord('q'):
            break
        
cap.release()
cv.destroyAllWindows()

关键改动说明

  1. 颜色空间转换:OpenCV捕获的视频帧是BGR格式,但MediaPipe的模型要求输入RGB格式,必须用cv.cvtColor做转换,否则检测会失效。
  2. 帧格式包装:MediaPipe的检测器无法直接处理OpenCV的numpy数组,需要用mp.Image把转换后的RGB帧包装成它支持的格式。
  3. 触发检测调用:在LIVE_STREAM模式下,必须调用detect_async方法传入处理好的图像和递增的时间戳,这样才会触发你定义的print_result回调函数完成检测。
  4. 可视化检测结果:新增了人脸框绘制逻辑,让你能直接在摄像头窗口看到检测到的人脸,而不是只能看控制台打印的文字。
  5. 结果传递:用全局变量把回调函数里的检测结果传给主循环,解决异步回调和主循环的结果同步问题。

额外提示

  • 你用的blaze_face_short_range.tflite模型适合检测2米以内的近距离人脸,如果需要检测更远的人脸,可以换成blaze_face_long_range.tflite模型。
  • 控制台的打印可以根据需要调整,比如只在检测到新人脸时打印,避免输出过于频繁。

备注:内容来源于stack exchange,提问作者Hugo

火山引擎 最新活动