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()
关键改动说明
- 颜色空间转换:OpenCV捕获的视频帧是BGR格式,但MediaPipe的模型要求输入RGB格式,必须用
cv.cvtColor做转换,否则检测会失效。 - 帧格式包装:MediaPipe的检测器无法直接处理OpenCV的numpy数组,需要用
mp.Image把转换后的RGB帧包装成它支持的格式。 - 触发检测调用:在LIVE_STREAM模式下,必须调用
detect_async方法传入处理好的图像和递增的时间戳,这样才会触发你定义的print_result回调函数完成检测。 - 可视化检测结果:新增了人脸框绘制逻辑,让你能直接在摄像头窗口看到检测到的人脸,而不是只能看控制台打印的文字。
- 结果传递:用全局变量把回调函数里的检测结果传给主循环,解决异步回调和主循环的结果同步问题。
额外提示
- 你用的
blaze_face_short_range.tflite模型适合检测2米以内的近距离人脸,如果需要检测更远的人脸,可以换成blaze_face_long_range.tflite模型。 - 控制台的打印可以根据需要调整,比如只在检测到新人脸时打印,避免输出过于频繁。
备注:内容来源于stack exchange,提问作者Hugo




