feat: 人员识别与管理模块 - MediaPipe人脸检测、人脸识别、人员库管理
This commit is contained in:
@@ -5,7 +5,7 @@ Local Analyzer - 本地视觉分析(无需大模型)
|
||||
功能:
|
||||
- 帧间差分:检测运动
|
||||
- 背景建模:检测前景物体
|
||||
- 人体检测:检测人员进出
|
||||
- 人员识别:检测并识别人物(新人员自动入库)
|
||||
- 亮度检测:检测光线变化
|
||||
- 自动判断是否需要调用大模型
|
||||
"""
|
||||
@@ -13,6 +13,18 @@ import cv2
|
||||
import numpy as np
|
||||
from pathlib import Path
|
||||
import datetime
|
||||
import sys
|
||||
import os
|
||||
|
||||
# 添加项目路径
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
try:
|
||||
from person_manager import person_manager
|
||||
HAS_PERSON_MANAGER = True
|
||||
except ImportError:
|
||||
HAS_PERSON_MANAGER = False
|
||||
print("[LocalAnalyzer] PersonManager not available")
|
||||
|
||||
|
||||
class LocalAnalyzer:
|
||||
@@ -104,40 +116,90 @@ class LocalAnalyzer:
|
||||
})
|
||||
self.motion_count += 1
|
||||
|
||||
# 2. 人体检测
|
||||
human_result = self._detect_human(current_frame)
|
||||
metrics['human_count'] = human_result['count']
|
||||
# 2. 人员检测与识别
|
||||
person_result = {'persons': [], 'total_count': 0, 'new_count': 0, 'known_count': 0}
|
||||
|
||||
# 记录人数变化
|
||||
human_count_change = human_result['count'] - self.prev_human_count
|
||||
metrics['human_count_change'] = human_count_change
|
||||
|
||||
if human_count_change > 0:
|
||||
events.append({
|
||||
'event_type': '人物活动',
|
||||
'description': f'检测到 {human_count_change} 人进入,当前共 {human_result["count"]} 人',
|
||||
'confidence': '高',
|
||||
'source': 'local'
|
||||
})
|
||||
self.human_count += human_count_change
|
||||
elif human_count_change < 0:
|
||||
events.append({
|
||||
'event_type': '人物活动',
|
||||
'description': f'检测到 {abs(human_count_change)} 人离开,当前剩 {human_result["count"]} 人',
|
||||
'confidence': '高',
|
||||
'source': 'local'
|
||||
})
|
||||
elif human_result['count'] > 0:
|
||||
# 人数没变但有人
|
||||
events.append({
|
||||
'event_type': '人物活动',
|
||||
'description': f'检测到 {human_result["count"]} 个人(无变化)',
|
||||
'confidence': '低',
|
||||
'source': 'local'
|
||||
})
|
||||
|
||||
# 更新前一帧人数(在 should_call_model 中更新)
|
||||
# self.prev_human_count = human_result['count']
|
||||
if HAS_PERSON_MANAGER:
|
||||
print(f"[LocalAnalyzer] Using PersonManager for face detection...")
|
||||
person_result = person_manager.analyze_image(image_path, save_new_person=True)
|
||||
|
||||
metrics['person_count'] = person_result['total_count']
|
||||
metrics['new_persons'] = person_result['new_count']
|
||||
metrics['known_persons'] = person_result['known_count']
|
||||
|
||||
# 记录人员变化
|
||||
prev_person_count = self.prev_human_count # 用之前的变量名
|
||||
person_count_change = person_result['total_count'] - prev_person_count
|
||||
metrics['person_count_change'] = person_count_change
|
||||
|
||||
for person in person_result['persons']:
|
||||
if person['is_new']:
|
||||
events.append({
|
||||
'event_type': '人物活动',
|
||||
'description': f'新人出现: {person["name"]},当前共 {person_result["total_count"]} 人',
|
||||
'confidence': '高',
|
||||
'source': 'local'
|
||||
})
|
||||
self.human_count += 1
|
||||
else:
|
||||
events.append({
|
||||
'event_type': '人物活动',
|
||||
'description': f'已知人员: {person["name"]},已访问 {person_manager.persons.get(person["person_id"], {}).get("visit_count", 1)} 次',
|
||||
'confidence': '高',
|
||||
'source': 'local'
|
||||
})
|
||||
|
||||
# 检测人员进出
|
||||
if person_count_change > 0:
|
||||
events.append({
|
||||
'event_type': '人员进出',
|
||||
'description': f'检测到 {person_count_change} 人进入,当前共 {person_result["total_count"]} 人',
|
||||
'confidence': '高',
|
||||
'source': 'local'
|
||||
})
|
||||
elif person_count_change < 0:
|
||||
events.append({
|
||||
'event_type': '人员进出',
|
||||
'description': f'检测到 {abs(person_count_change)} 人离开,当前剩 {person_result["total_count"]} 人',
|
||||
'confidence': '高',
|
||||
'source': 'local'
|
||||
})
|
||||
|
||||
# 更新前一帧人数
|
||||
self.prev_human_count = person_result['total_count']
|
||||
|
||||
else:
|
||||
# 使用传统人体检测(备用)
|
||||
human_result = self._detect_human(current_frame)
|
||||
metrics['human_count'] = human_result['count']
|
||||
|
||||
human_count_change = human_result['count'] - self.prev_human_count
|
||||
metrics['human_count_change'] = human_count_change
|
||||
|
||||
if human_count_change > 0:
|
||||
events.append({
|
||||
'event_type': '人物活动',
|
||||
'description': f'检测到 {human_count_change} 人进入,当前共 {human_result["count"]} 人',
|
||||
'confidence': '高',
|
||||
'source': 'local'
|
||||
})
|
||||
self.human_count += human_count_change
|
||||
elif human_count_change < 0:
|
||||
events.append({
|
||||
'event_type': '人物活动',
|
||||
'description': f'检测到 {abs(human_count_change)} 人离开,当前剩 {human_result["count"]} 人',
|
||||
'confidence': '高',
|
||||
'source': 'local'
|
||||
})
|
||||
elif human_result['count'] > 0:
|
||||
events.append({
|
||||
'event_type': '人物活动',
|
||||
'description': f'检测到 {human_result["count"]} 个人(无变化)',
|
||||
'confidence': '低',
|
||||
'source': 'local'
|
||||
})
|
||||
|
||||
self.prev_human_count = human_result['count']
|
||||
|
||||
# 3. 亮度检测
|
||||
brightness_result = self._detect_brightness_change(current_gray, prev_image_path)
|
||||
@@ -306,23 +368,25 @@ class LocalAnalyzer:
|
||||
"""判断是否需要调用大模型"""
|
||||
|
||||
# 条件1:人数变化(最重要)
|
||||
current_human_count = metrics.get('human_count', 0)
|
||||
human_count_change = abs(current_human_count - self.prev_human_count)
|
||||
current_person_count = metrics.get('person_count', metrics.get('human_count', 0))
|
||||
person_count_change = metrics.get('person_count_change', metrics.get('human_count_change', 0))
|
||||
|
||||
# 更新前一帧人数
|
||||
self.prev_human_count = current_human_count
|
||||
|
||||
if human_count_change >= self.config['human_count_change_threshold']:
|
||||
print(f"[LocalAnalyzer] Human count changed: {self.prev_human_count} -> {current_human_count}, triggering model")
|
||||
# 更新前一帧人数(如果还没更新)
|
||||
if abs(person_count_change) >= self.config['human_count_change_threshold']:
|
||||
print(f"[LocalAnalyzer] Person count changed: {current_person_count - person_count_change} -> {current_person_count}, triggering model")
|
||||
return True
|
||||
|
||||
# 条件2:运动面积超过阈值(排除有人但不动的情况)
|
||||
# 只有在没有人变化时才用这个条件
|
||||
# 条件2:检测到新人
|
||||
if metrics.get('new_persons', 0) > 0:
|
||||
print(f"[LocalAnalyzer] New person detected: {metrics.get('new_persons', 0)}, triggering model")
|
||||
return True
|
||||
|
||||
# 条件3:运动面积超过阈值(排除有人但不动的情况)
|
||||
if metrics.get('motion_ratio', 0) > self.config['trigger_model_threshold'] * 2:
|
||||
print(f"[LocalAnalyzer] Large motion detected: {metrics.get('motion_ratio', 0):.2%}")
|
||||
return True
|
||||
|
||||
# 条件3:亮度大幅变化(灯开关等)
|
||||
# 条件4:亮度大幅变化(灯开关等)
|
||||
if abs(metrics.get('brightness_change', 0)) > self.config['brightness_change_threshold'] * 2:
|
||||
print(f"[LocalAnalyzer] Brightness changed: {metrics.get('brightness_change', 0)}")
|
||||
return True
|
||||
|
||||
Reference in New Issue
Block a user