feature:加入功能,小朋友人脸识别与分类。
This commit is contained in:
@@ -74,18 +74,19 @@ class FaceAnalyzer:
|
|||||||
|
|
||||||
def analyze_face(self, image_path, face_area=None):
|
def analyze_face(self, image_path, face_area=None):
|
||||||
"""分析人脸,获取特征向量"""
|
"""分析人脸,获取特征向量"""
|
||||||
|
temp_path = None
|
||||||
try:
|
try:
|
||||||
# 检查文件是否存在
|
# 检查文件是否存在
|
||||||
if not os.path.exists(image_path):
|
if not os.path.exists(image_path):
|
||||||
self.logger.error(f"图片文件不存在: {image_path}")
|
self.logger.error(f"图片文件不存在: {image_path}")
|
||||||
return None
|
return None, None
|
||||||
|
|
||||||
# 检查文件是否可读
|
# 检查文件是否可读
|
||||||
try:
|
try:
|
||||||
img = cv2.imread(image_path)
|
img = cv2.imread(image_path)
|
||||||
if img is None:
|
if img is None:
|
||||||
self.logger.error(f"无法读取图片: {image_path}")
|
self.logger.error(f"无法读取图片: {image_path}")
|
||||||
return None
|
return None, None
|
||||||
|
|
||||||
# 如果指定了人脸区域,裁剪图片
|
# 如果指定了人脸区域,裁剪图片
|
||||||
if face_area:
|
if face_area:
|
||||||
@@ -98,7 +99,7 @@ class FaceAnalyzer:
|
|||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.error(f"读取图片失败: {image_path}, 错误: {e}")
|
self.logger.error(f"读取图片失败: {image_path}, 错误: {e}")
|
||||||
return None
|
return None, None
|
||||||
|
|
||||||
# 提取人脸特征向量用于后续比对
|
# 提取人脸特征向量用于后续比对
|
||||||
embedding_result = DeepFace.represent(
|
embedding_result = DeepFace.represent(
|
||||||
@@ -127,26 +128,20 @@ class FaceAnalyzer:
|
|||||||
embedding = [float(x) for x in embedding]
|
embedding = [float(x) for x in embedding]
|
||||||
except (TypeError, ValueError):
|
except (TypeError, ValueError):
|
||||||
self.logger.error(f"无法将嵌入向量转换为浮点数列表: {image_path}")
|
self.logger.error(f"无法将嵌入向量转换为浮点数列表: {image_path}")
|
||||||
return None
|
return None, temp_path
|
||||||
|
|
||||||
self.logger.info(f"成功提取人脸特征向量: {image_path}")
|
self.logger.info(f"成功提取人脸特征向量: {image_path}")
|
||||||
|
|
||||||
# 如果使用了临时文件,删除它
|
# 不再进行年龄判断,直接返回特征向量和临时文件路径
|
||||||
if face_area and os.path.exists(f"{image_path}.temp.jpg"):
|
|
||||||
try:
|
|
||||||
os.remove(f"{image_path}.temp.jpg")
|
|
||||||
except Exception as e:
|
|
||||||
self.logger.warning(f"删除临时文件失败: {e}")
|
|
||||||
|
|
||||||
# 不再进行年龄判断,直接返回特征向量
|
|
||||||
return {
|
return {
|
||||||
'embedding': embedding,
|
'embedding': embedding,
|
||||||
'is_kid': True # 默认所有人脸都处理
|
'is_kid': True # 默认所有人脸都处理
|
||||||
}
|
}, temp_path
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.error(f"人脸分析失败: {image_path}, 错误: {e}")
|
self.logger.error(f"人脸分析失败: {image_path}, 错误: {e}")
|
||||||
self.logger.error(traceback.format_exc()) # 打印完整的错误堆栈
|
self.logger.error(traceback.format_exc()) # 打印完整的错误堆栈
|
||||||
return None
|
return None, temp_path
|
||||||
|
|
||||||
def is_kid(self, face_info):
|
def is_kid(self, face_info):
|
||||||
"""判断是否为小朋友 - 现在总是返回True"""
|
"""判断是否为小朋友 - 现在总是返回True"""
|
||||||
@@ -529,6 +524,8 @@ class KidPhotoExtractorPlugin(MessagePluginInterface):
|
|||||||
def _run_analysis_task(self, group_key, source_dir, output_dir, wcf, target, sender):
|
def _run_analysis_task(self, group_key, source_dir, output_dir, wcf, target, sender):
|
||||||
"""在后台运行分析任务"""
|
"""在后台运行分析任务"""
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
|
temp_files = [] # 用于跟踪所有创建的临时文件
|
||||||
|
|
||||||
try:
|
try:
|
||||||
is_full = self.analysis_tasks[group_key].get("is_full", False)
|
is_full = self.analysis_tasks[group_key].get("is_full", False)
|
||||||
self.LOG.info(f"开始{'全量' if is_full else '增量'}分析任务: {source_dir}")
|
self.LOG.info(f"开始{'全量' if is_full else '增量'}分析任务: {source_dir}")
|
||||||
@@ -623,9 +620,13 @@ class KidPhotoExtractorPlugin(MessagePluginInterface):
|
|||||||
for face in faces:
|
for face in faces:
|
||||||
# 分析人脸
|
# 分析人脸
|
||||||
face_region = face.get('facial_area', None)
|
face_region = face.get('facial_area', None)
|
||||||
face_info = self.face_analyzer.analyze_face(image_path, face_region)
|
face_info, temp_file = self.face_analyzer.analyze_face(image_path, face_region)
|
||||||
|
|
||||||
if face_info: # 不再判断是否为小朋友
|
# 如果创建了临时文件,添加到跟踪列表
|
||||||
|
if temp_file:
|
||||||
|
temp_files.append(temp_file)
|
||||||
|
|
||||||
|
if face_info:
|
||||||
# 保存人脸特征
|
# 保存人脸特征
|
||||||
all_faces.append(face_info['embedding'])
|
all_faces.append(face_info['embedding'])
|
||||||
face_images.append(image_path)
|
face_images.append(image_path)
|
||||||
@@ -752,6 +753,16 @@ class KidPhotoExtractorPlugin(MessagePluginInterface):
|
|||||||
import gc
|
import gc
|
||||||
gc.collect()
|
gc.collect()
|
||||||
|
|
||||||
|
def _cleanup_temp_files(self, temp_files):
|
||||||
|
"""清理所有临时文件"""
|
||||||
|
for temp_file in temp_files:
|
||||||
|
try:
|
||||||
|
if os.path.exists(temp_file):
|
||||||
|
os.remove(temp_file)
|
||||||
|
self.LOG.info(f"已删除临时文件: {temp_file}")
|
||||||
|
except Exception as e:
|
||||||
|
self.LOG.error(f"删除临时文件失败: {temp_file}, 错误: {e}")
|
||||||
|
|
||||||
def _save_analysis_result(self, group_key, result):
|
def _save_analysis_result(self, group_key, result):
|
||||||
"""保存分析结果到Redis"""
|
"""保存分析结果到Redis"""
|
||||||
try:
|
try:
|
||||||
|
|||||||
Reference in New Issue
Block a user