Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.test
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
TESTING=true
4 changes: 0 additions & 4 deletions .gitattributes

This file was deleted.

78 changes: 78 additions & 0 deletions app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# ...existing imports...
from pose.verification_manager import VerificationManager

class MeetApp:
def __init__(self):
# ...existing init code...
self.verification_manager = VerificationManager()

@app.route('/verify_identity', methods=['POST'])
def verify_identity(self):
try:
# 获取当前帧
if not self.camera or not self.camera.is_running:
return jsonify({
'success': False,
'message': '请先启动摄像头'
})

frame = self.camera.read_frame()
if frame is None:
return jsonify({
'success': False,
'message': '无法获取摄像头画面'
})

# 验证身份
result = self.verification_manager.verify_identity(frame)

return jsonify({
'success': True,
'verification': {
'passed': result.success,
'message': result.message,
'confidence': result.confidence
}
})

except Exception as e:
logger.error(f"身份验证失败: {str(e)}")
return jsonify({
'success': False,
'message': str(e)
})

@app.route('/capture_reference', methods=['POST'])
def capture_reference(self):
try:
if not self.camera or not self.camera.is_running:
return jsonify({
'success': False,
'message': '请先启动摄像头'
})

frame = self.camera.read_frame()
if frame is None:
return jsonify({
'success': False,
'message': '无法获取摄像头画面'
})

# 捕获参考帧
result = self.verification_manager.capture_reference(frame)

return jsonify({
'success': True,
'verification': {
'passed': result.success,
'message': result.message,
'confidence': result.confidence
}
})

except Exception as e:
logger.error(f"捕获参考帧失败: {str(e)}")
return jsonify({
'success': False,
'message': str(e)
})
19 changes: 14 additions & 5 deletions camera/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ def __init__(self, config: Dict = None):
self.is_running = False
self.frame_count = 0
self.start_time = time.time()
self._current_fps = 0 # 改为私有属性
self._last_fps_check = time.time()
self._frames_since_check = 0

# 从配置加载参数
self.config = config or {}
Expand Down Expand Up @@ -126,7 +129,7 @@ def stop(self) -> bool:
return False

def read_frame(self) -> Optional[cv2.Mat]:
"""读取一帧图像
"""读取一帧并更新统计信息

Returns:
Optional[cv2.Mat]: 图像帧,失败返回None
Expand All @@ -140,6 +143,15 @@ def read_frame(self) -> Optional[cv2.Mat]:
return None

self.frame_count += 1
self._frames_since_check += 1

# 每秒更新一次 FPS
now = time.time()
if now - self._last_fps_check >= 1.0:
self._current_fps = self._frames_since_check # 使用私有属性
self._frames_since_check = 0
self._last_fps_check = now

return frame

except Exception as e:
Expand All @@ -151,9 +163,7 @@ def current_fps(self) -> float:
"""获取当前帧率"""
if not self.is_running:
return 0.0

elapsed = time.time() - self.start_time
return self.frame_count / max(elapsed, 0.001)
return self._current_fps # 返回私有属性

def release(self):
"""释放资源"""
Expand Down Expand Up @@ -228,4 +238,3 @@ def reset_settings(self) -> bool:
except Exception as e:
logger.error(f"重置相机设置失败: {e}")
return False

193 changes: 130 additions & 63 deletions config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,9 @@
# MediaPipe 配置
MEDIAPIPE_CONFIG = {
'pose': {
'static_mode': False,
'static_image_mode': False,
'model_complexity': 1,
'enable_segmentation': False,
'static_image_mode': False, # 修改 'static_mode' 为 'static_image_mode'
'model_complexity': 2,
'enable_segmentation': True,
'smooth_landmarks': True,
'min_detection_confidence': 0.5,
'min_tracking_confidence': 0.5
Expand All @@ -47,11 +46,13 @@
'static_image_mode': False,
'max_num_hands': 2,
'min_detection_confidence': 0.5,
'min_tracking_confidence': 0.5
'min_tracking_confidence': 0.5,
'model_complexity': 1
},
'face_mesh': {
'static_image_mode': False,
'max_num_faces': 1,
'refine_landmarks': True, # 启用细节关键点
'min_detection_confidence': 0.5,
'min_tracking_confidence': 0.5
}
Expand All @@ -60,86 +61,152 @@
# 添加姿态检测和变形相关配置
POSE_CONFIG = {
'detector': {
# 基本参数
'static_mode': False,
'model_complexity': 1,
'enable_segmentation': False,
'model_complexity': 2,
'smooth_landmarks': True,
'min_detection_confidence': 0.5,
'min_tracking_confidence': 0.5,
'min_confidence': 0.5,
'min_confidence': 0.3, # 降低置信度阈值以提高检测率
'smooth_factor': 0.5,

# 身体关键点定义 - 移到前面来
'body_landmarks': {
'nose': 0,
'left_eye_inner': 1,
'left_eye': 2,
'left_eye_outer': 3,
'right_eye_inner': 4,
'right_eye': 5,
'right_eye_outer': 6,
'left_ear': 7,
'right_ear': 8,
'mouth_left': 9,
'mouth_right': 10,
'left_shoulder': 11,
'right_shoulder': 12,
'left_elbow': 13,
'right_elbow': 14,
'left_wrist': 15,
'right_wrist': 16,
'left_pinky': 17,
'right_pinky': 18,
'left_index': 19,
'right_index': 20,
'left_thumb': 21,
'right_thumb': 22,
'left_hip': 23,
'right_hip': 24,
'left_knee': 25,
'right_knee': 26,
'left_ankle': 27,
'right_ankle': 28,
'left_heel': 29,
'right_heel': 30,
'left_foot_index': 31,
'right_foot_index': 32
},

# 面部关键点 - 移到前面来
'face_landmarks': {
'contour': list(range(0, 17)) + list(range(297, 318)), # 脸部轮廓
'left_eye': list(range(362, 374)), # 左眼
'right_eye': list(range(133, 145)), # 右眼
'left_eyebrow': list(range(276, 283)), # 左眉毛
'right_eyebrow': list(range(46, 53)), # 右眉毛
'nose': list(range(168, 175)), # 鼻子
'mouth_outer': list(range(0, 17)), # 外唇
'mouth_inner': list(range(78, 87)) # 内唇
},

# 手部关键点 - 移到前面来
'hand_landmarks': {
'wrist': 0,
'thumb': list(range(1, 5)),
'index_finger': list(range(5, 9)),
'middle_finger': list(range(9, 13)),
'ring_finger': list(range(13, 17)),
'pinky': list(range(17, 21))
},

# 关键点定义 - 现在可以安全引用上面定义的部分
'keypoints': {
# 躯干
'nose': {'id': 0, 'name': 'nose', 'parent_id': -1},
'neck': {'id': 1, 'name': 'neck', 'parent_id': 0},
'right_shoulder': {'id': 12, 'name': 'right_shoulder', 'parent_id': 1},
'left_shoulder': {'id': 11, 'name': 'left_shoulder', 'parent_id': 1},
'right_hip': {'id': 24, 'name': 'right_hip', 'parent_id': 1},
'left_hip': {'id': 23, 'name': 'left_hip', 'parent_id': 1},

# 手臂
'right_elbow': {'id': 14, 'name': 'right_elbow', 'parent_id': 12},
'left_elbow': {'id': 13, 'name': 'left_elbow', 'parent_id': 11},
'right_wrist': {'id': 16, 'name': 'right_wrist', 'parent_id': 14},
'left_wrist': {'id': 15, 'name': 'left_wrist', 'parent_id': 13},

# 腿部
'right_knee': {'id': 26, 'name': 'right_knee', 'parent_id': 24},
'left_knee': {'id': 25, 'name': 'left_knee', 'parent_id': 23},
'right_ankle': {'id': 28, 'name': 'right_ankle', 'parent_id': 26},
'left_ankle': {'id': 27, 'name': 'left_ankle', 'parent_id': 25}
'body': 'body_landmarks', # 使用字符串引用
'face': 'face_landmarks',
'hands': 'hand_landmarks'
},

# 关键点连接定义
'connections': {
'torso': ['left_shoulder', 'right_shoulder', 'right_hip', 'left_hip'],
'left_upper_arm': ['left_shoulder', 'left_elbow'],
'left_lower_arm': ['left_elbow', 'left_wrist'],
'right_upper_arm': ['right_shoulder', 'right_elbow'],
'right_lower_arm': ['right_elbow', 'right_wrist'],
'left_upper_leg': ['left_hip', 'left_knee'],
'left_lower_leg': ['left_knee', 'left_ankle'],
'right_upper_leg': ['right_hip', 'right_knee'],
'right_lower_leg': ['right_knee', 'right_ankle']
# 面部连接
'face': {
'contour': [(i, i+1) for i in range(0, 16)] + [(i, i+1) for i in range(297, 317)],
'left_eye': [(i, i+1) for i in range(362, 373)] + [(373, 362)],
'right_eye': [(i, i+1) for i in range(133, 144)] + [(144, 133)],
'left_eyebrow': [(i, i+1) for i in range(276, 282)],
'right_eyebrow': [(i, i+1) for i in range(46, 52)],
'nose': [(i, i+1) for i in range(168, 174)],
'mouth': [(i, i+1) for i in range(0, 16)] + [(0, 16)]
},

# 手部连接
'hands': {
'thumb': [(0,1), (1,2), (2,3), (3,4)],
'index': [(0,5), (5,6), (6,7), (7,8)],
'middle': [(0,9), (9,10), (10,11), (11,12)],
'ring': [(0,13), (13,14), (14,15), (15,16)],
'pinky': [(0,17), (17,18), (18,19), (19,20)]
},

# 身体连接
'body': {
'torso': [
(11,12), (11,23), (12,24), (23,24), # 躯干
(11,13), (13,15), (12,14), (14,16), # 手臂
(23,25), (25,27), (24,26), (26,28) # 腿部
],
'face': [
(0,1), (1,2), (2,3), (3,7), # 左侧脸
(0,4), (4,5), (5,6), (6,8), # 右侧脸
(9,10) # 嘴
],
'feet': [
(27,29), (29,31), (28,30), (30,32) # 脚部
]
}
}
},

# 变形器配置
'deformer': {
'smoothing_window': 5,
'smoothing_factor': 0.3,
'blend_radius': 20,
'min_scale': 0.5,
'max_scale': 2.0,
'control_point_radius': 50
'control_point_radius': 50,
'interpolation_method': 'linear',
'edge_preservation': True,
'motion_threshold': 0.1
},

# 绘制器配置
'drawer': {
'colors': {
'face': (255, 0, 0), # 蓝色
'face': (255, 200, 0), # 淡蓝色
'body': (0, 255, 0), # 绿色
'hands': (0, 255, 255), # 黄色
'joints': (0, 0, 255) # 红色
'joints': (255, 0, 0) # 红色
},
'face_colors': {
'contour': (200, 180, 130), # 淡金色
'eyebrow': (180, 120, 90), # 深棕色
'eye': (120, 150, 230), # 淡蓝色
'nose': (150, 200, 180), # 青绿色
'mouth': (140, 160, 210) # 淡紫色
}
},
'smoother': {
# 基础平滑参数
'temporal_weight': 0.8,
'spatial_weight': 0.5,

# 变形平滑参数
'deform_threshold': 30,
'edge_width': 3,
'motion_scale': 0.5,

# 质量评估参数
'quality_weights': {
'temporal': 0.4,
'spatial': 0.3,
'edge': 0.3
'line_thickness': {
'face': 1,
'body': 2,
'hands': 1
},
'point_size': {
'face': 1,
'body': 3,
'hands': 2
}
}
}
}
Binary file added debug_output/comparison.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added debug_output/current_frame.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added debug_output/deformed_frame.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added debug_output/difference_map.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added debug_output/original_frame.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added debug_output/pose_detection.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added debug_output/reference_frame.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading