fix: 使用 MediaPipe 人脸关键点作为特征,不依赖 dlib

This commit is contained in:
2026-04-16 18:59:40 +08:00
parent 55c6ad88c8
commit 7e7a967eb4

View File

@@ -150,7 +150,9 @@ class PersonManager:
return faces
def extract_face_encoding(self, image, face_bbox):
"""提取人脸特征
"""提取人脸特征(用于识别是否为同一个人)
使用 MediaPipe 的人脸关键点作为特征,不依赖 dlib
Args:
image: 图片
@@ -177,25 +179,46 @@ class PersonManager:
# 提取人脸区域
face_image = image[y:y+h, x:x+w]
# 方法1使用 face_recognition如果安装了
if HAS_FACE_REC:
# 使用 face_recognition 库
rgb_face = cv2.cvtColor(face_image, cv2.COLOR_BGR2RGB)
encodings = face_recognition.face_encodings(rgb_face)
if len(encodings) > 0:
return encodings[0]
try:
rgb_face = cv2.cvtColor(face_image, cv2.COLOR_BGR2RGB)
encodings = face_recognition.face_encodings(rgb_face)
if len(encodings) > 0:
return encodings[0]
except:
pass
# 简单特征:使用颜色直方图作为特征
# 将人脸缩放到固定大小
# 方法2使用 MediaPipe 人脸关键点(推荐)
if HAS_MEDIAPIPE:
try:
mp_face_mesh = mp.solutions.face_mesh
face_mesh = mp_face_mesh.FaceMesh(static_image_mode=True, max_num_faces=1)
rgb_face = cv2.cvtColor(face_image, cv2.COLOR_BGR2RGB)
results = face_mesh.process(rgb_face)
if results.multi_face_landmarks:
# 提取关键点坐标作为特征
landmarks = results.multi_face_landmarks[0]
features = []
for landmark in landmarks.landmark:
features.extend([landmark.x, landmark.y, landmark.z])
face_mesh.close()
return np.array(features)
except:
pass
# 方法3使用颜色直方图最简单备用
face_resized = cv2.resize(face_image, (64, 64))
# 计算 HSV 直方图
hsv = cv2.cvtColor(face_resized, cv2.COLOR_BGR2HSV)
hist_h = cv2.calcHist([hsv], [0], None, [16], [0, 180])
hist_s = cv2.calcHist([hsv], [1], None, [16], [0, 256])
hist_v = cv2.calcHist([hsv], [2], None, [16], [0, 256])
# 合并特征
feature = np.concatenate([
cv2.normalize(hist_h, hist_h).flatten(),
cv2.normalize(hist_s, hist_s).flatten(),