fix: 使用 MediaPipe 人脸关键点作为特征,不依赖 dlib
This commit is contained in:
+35
-12
@@ -150,7 +150,9 @@ class PersonManager:
|
|||||||
return faces
|
return faces
|
||||||
|
|
||||||
def extract_face_encoding(self, image, face_bbox):
|
def extract_face_encoding(self, image, face_bbox):
|
||||||
"""提取人脸特征
|
"""提取人脸特征(用于识别是否为同一个人)
|
||||||
|
|
||||||
|
使用 MediaPipe 的人脸关键点作为特征,不依赖 dlib
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
image: 图片
|
image: 图片
|
||||||
@@ -177,25 +179,46 @@ class PersonManager:
|
|||||||
# 提取人脸区域
|
# 提取人脸区域
|
||||||
face_image = image[y:y+h, x:x+w]
|
face_image = image[y:y+h, x:x+w]
|
||||||
|
|
||||||
|
# 方法1:使用 face_recognition(如果安装了)
|
||||||
if HAS_FACE_REC:
|
if HAS_FACE_REC:
|
||||||
# 使用 face_recognition 库
|
try:
|
||||||
rgb_face = cv2.cvtColor(face_image, cv2.COLOR_BGR2RGB)
|
rgb_face = cv2.cvtColor(face_image, cv2.COLOR_BGR2RGB)
|
||||||
encodings = face_recognition.face_encodings(rgb_face)
|
encodings = face_recognition.face_encodings(rgb_face)
|
||||||
|
if len(encodings) > 0:
|
||||||
if len(encodings) > 0:
|
return 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))
|
face_resized = cv2.resize(face_image, (64, 64))
|
||||||
|
|
||||||
# 计算 HSV 直方图
|
|
||||||
hsv = cv2.cvtColor(face_resized, cv2.COLOR_BGR2HSV)
|
hsv = cv2.cvtColor(face_resized, cv2.COLOR_BGR2HSV)
|
||||||
|
|
||||||
hist_h = cv2.calcHist([hsv], [0], None, [16], [0, 180])
|
hist_h = cv2.calcHist([hsv], [0], None, [16], [0, 180])
|
||||||
hist_s = cv2.calcHist([hsv], [1], None, [16], [0, 256])
|
hist_s = cv2.calcHist([hsv], [1], None, [16], [0, 256])
|
||||||
hist_v = cv2.calcHist([hsv], [2], None, [16], [0, 256])
|
hist_v = cv2.calcHist([hsv], [2], None, [16], [0, 256])
|
||||||
|
|
||||||
# 合并特征
|
|
||||||
feature = np.concatenate([
|
feature = np.concatenate([
|
||||||
cv2.normalize(hist_h, hist_h).flatten(),
|
cv2.normalize(hist_h, hist_h).flatten(),
|
||||||
cv2.normalize(hist_s, hist_s).flatten(),
|
cv2.normalize(hist_s, hist_s).flatten(),
|
||||||
|
|||||||
Reference in New Issue
Block a user