diff --git a/plugins/kid_photo_extractor/main.py b/plugins/kid_photo_extractor/main.py index 6f97743..e00c3a7 100644 --- a/plugins/kid_photo_extractor/main.py +++ b/plugins/kid_photo_extractor/main.py @@ -67,6 +67,12 @@ class FaceAnalyzer: # 过滤掉可能的误检 valid_faces = [] for face in faces: + # 检查置信度,过滤掉低置信度的检测结果 + confidence = face.get('confidence', 0) + if confidence < 0.8: # 提高置信度阈值到0.8 + self.logger.info(f"过滤掉低置信度人脸: {confidence}") + continue + # 检查人脸区域的大小,过滤掉太小的区域(可能是图标) if 'facial_area' in face: area = face['facial_area'] @@ -74,12 +80,22 @@ class FaceAnalyzer: face_height = area['h'] # 过滤条件:人脸必须足够大(通常图标较小) - min_face_size = 40 # 最小人脸尺寸(像素) + min_face_size = 60 # 增加最小人脸尺寸(像素) if face_width > min_face_size and face_height > min_face_size: # 检查人脸宽高比,过滤掉不合理的比例 aspect_ratio = face_width / face_height - if 0.5 <= aspect_ratio <= 2.0: # 正常人脸的宽高比范围 - valid_faces.append(face) + if 0.7 <= aspect_ratio <= 1.5: # 缩小人脸宽高比范围,更接近真实人脸 + # 计算人脸区域占图片的比例,过滤掉太小的区域 + img_height, img_width = img.shape[:2] + face_area_ratio = (face_width * face_height) / (img_width * img_height) + if 0.01 <= face_area_ratio <= 0.9: # 人脸区域应该在合理范围内 + valid_faces.append(face) + else: + self.logger.info(f"过滤掉不合理区域比例的人脸: {face_area_ratio}") + else: + self.logger.info(f"过滤掉不合理宽高比的人脸: {aspect_ratio}") + else: + self.logger.info(f"过滤掉过小的人脸: {face_width}x{face_height}") # 记录检测到的人脸数量 self.logger.info(f"在图片 {image_path} 中检测到 {len(faces)} 个人脸,有效人脸 {len(valid_faces)} 个") @@ -114,25 +130,27 @@ class FaceAnalyzer: temp_path = f"{image_path}.temp.jpg" cv2.imwrite(temp_path, img) - # 二次验证:使用人脸验证模型确认这确实是一张人脸 + # 使用人脸检测来验证这是否是一张人脸,而不是使用verify try: - verification = DeepFace.verify( - img1_path=temp_path, - enforce_detection=False, - detector_backend='retinaface', - model_name='VGG-Face', # 使用VGG-Face模型进行验证 - distance_metric='cosine' + # 使用DeepFace的detect_face函数检测是否包含人脸 + detection = DeepFace.extract_faces( + img_path=temp_path, + enforce_detection=True, # 强制检测 + detector_backend='retinaface' ) - # 如果验证失败(不是人脸),则返回None - if not verification.get('verified', False) and verification.get('distance', 0) > 0.5: + # 如果没有检测到人脸,则返回None + if not detection or len(detection) == 0: self.logger.info(f"二次验证失败,可能不是真实人脸: {image_path}") if os.path.exists(temp_path): os.remove(temp_path) return None, None except Exception as e: - # 验证失败不中断流程,只记录日志 + # 如果强制检测失败,说明可能不是人脸 self.logger.warning(f"人脸二次验证失败: {e}") + if os.path.exists(temp_path): + os.remove(temp_path) + return None, None image_path = temp_path @@ -144,7 +162,7 @@ class FaceAnalyzer: embedding_result = DeepFace.represent( img_path=image_path, model_name='ArcFace', # 使用ArcFace模型,对不同年龄段人脸效果更好 - enforce_detection=False, + enforce_detection=True, # 改为True,确保是人脸 detector_backend='retinaface' # 使用更精确的检测器 ) @@ -192,7 +210,7 @@ class FaceAnalyzer: class FaceGrouper: """人脸分组器,负责对人脸进行聚类分组""" - def __init__(self, eps=0.5, min_samples=3): + def __init__(self, eps=0.4, min_samples=4): # 减小eps值,增加min_samples值 self.eps = eps # DBSCAN的邻域半径 self.min_samples = min_samples # 形成核心点所需的最小样本数 self.logger = logging.getLogger("Plugin.KidPhotoExtractor.FaceGrouper")