diff --git a/person_manager.py b/person_manager.py index 06c7d09..50a1a95 100644 --- a/person_manager.py +++ b/person_manager.py @@ -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(),