Yunet模型人脸识别:外接摄像头人脸框偏移问题求助
外接Webcam人脸检测框偏移问题解决方案
问题描述
使用Mac内置摄像头时人脸检测框位置准确,但切换为外接Webcam后,检测框与人脸位置严重偏移。当前使用OpenCV 4.6.0.66,升级OpenCV后问题仍未解决。
解决方案
1. 取消检测前的图像缩放操作
原代码中对高分辨率图像的缩放会导致检测器基于缩放后的图像计算坐标,后续直接映射到原始尺寸图像绘制时出现偏移。修改recognize_face函数,移除不必要的缩放逻辑:
def recognize_face(image, face_detector, face_recognizer, file_name=None): channels = 1 if len(image.shape) == 2 else image.shape[2] if channels == 1: image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR) if channels == 4: image = cv2.cvtColor(image, cv2.COLOR_BGRA2BGR) # 注释掉原缩放逻辑,避免尺寸不匹配 # if image.shape[0] > 1000: # image = cv2.resize(image, (0, 0), # fx=500 / image.shape[0], fy=500 / image.shape[0]) height, width, _ = image.shape face_detector.setInputSize((width, height)) try: dts = time.time() _, faces = face_detector.detect(image) if file_name is not None: assert len(faces) > 0, f'the file {file_name} has no face' faces = faces if faces is not None else [] features = [] print(f'time detection = {time.time() - dts}') for face in faces: rts = time.time() aligned_face = face_recognizer.alignCrop(image, face) feat = face_recognizer.feature(aligned_face) print(f'time recognition = {time.time() - rts}') features.append(feat) return features, faces except Exception as e: print(e) print(file_name) return None, None
2. 强制设置Webcam分辨率
外接摄像头可能默认输出非标准分辨率,导致OpenCV读取的帧尺寸与实际渲染尺寸不符。在初始化摄像头时手动设置固定分辨率(根据你的Webcam支持参数调整):
capture = cv2.VideoCapture(1) if not capture.isOpened(): sys.exit() # 强制设置摄像头分辨率,示例为1280x720 capture.set(cv2.CAP_PROP_FRAME_WIDTH, 1280) capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)
3. 校验检测框坐标范围
若上述方法无效,添加坐标边界校验,确保检测框始终在图像范围内:
for idx, (face, feature) in enumerate(zip(faces, fetures)): result, user = match(face_recognizer, feature, dictionary) height, width = image.shape[:2] # 修正坐标,避免超出图像边界 x1 = max(0, min(int(face[0]), width)) y1 = max(0, min(int(face[1]), height)) x2 = max(0, min(int(face[0] + face[2]), width)) y2 = max(0, min(int(face[1] + face[3]), height)) color = (0, 255, 0) if result else (0, 0, 255) thickness = 2 cv2.rectangle(image, (x1, y1), (x2, y2), color, thickness, cv2.LINE_AA) id_name, score = user if result else (f"unknown_{idx}", 0.0) text = "{0} ({1:.2f})".format(id_name, score) position = (x1, y1 - 10) font = cv2.FONT_HERSHEY_SIMPLEX scale = 0.6 cv2.putText(image, text, position, font, scale, color, thickness, cv2.LINE_AA)
原理说明
外接Webcam的帧尺寸、像素格式与内置摄像头存在差异,原代码的缩放操作破坏了检测器输入尺寸与图像显示尺寸的一致性,导致检测坐标映射错误。通过取消缩放、强制固定分辨率、校验坐标边界,可确保检测器计算的坐标与实际图像尺寸完全匹配,解决偏移问题。
内容的提问来源于stack exchange,提问作者Carlos Gajardo
相关产品推荐
相关产品推荐

