|
|
@@ -468,13 +468,22 @@ class Coordinator:
|
|
|
|
|
|
# 过滤有效人员
|
|
|
valid_detections = []
|
|
|
+ low_conf_count = 0
|
|
|
for det in detections:
|
|
|
if det.class_name != 'person':
|
|
|
continue
|
|
|
if det.confidence < person_threshold:
|
|
|
+ low_conf_count += 1
|
|
|
continue
|
|
|
valid_detections.append(det)
|
|
|
|
|
|
+ # 【调试日志】显示过滤结果
|
|
|
+ if detections:
|
|
|
+ logger.info(f"[跟踪] 检测到 {len(detections)} 个目标, 置信度>={person_threshold} 的有 {len(valid_detections)} 个 (过滤掉 {low_conf_count} 个)")
|
|
|
+
|
|
|
+ if not valid_detections:
|
|
|
+ return
|
|
|
+
|
|
|
with self.targets_lock:
|
|
|
# 匹配阈值:位置距离小于此值认为是同一目标
|
|
|
MATCH_THRESHOLD = 0.15 # 画面比例
|
|
|
@@ -1685,9 +1694,17 @@ class SequentialCoordinator(AsyncCoordinator):
|
|
|
# 更新跟踪目标
|
|
|
self._update_tracking_targets(detections, frame_size)
|
|
|
|
|
|
+ # 【调试日志】检查跟踪目标数量
|
|
|
+ with self.targets_lock:
|
|
|
+ tracking_count = len(self.tracking_targets)
|
|
|
+ logger.info(f"[顺序模式] 检测到 {len(detections)} 个目标, 跟踪列表 {tracking_count} 个")
|
|
|
+
|
|
|
# 获取有效目标列表
|
|
|
targets = self._get_all_valid_targets()
|
|
|
|
|
|
+ # 【调试日志】显示有效目标数量
|
|
|
+ logger.info(f"[顺序模式] 有效目标数量: {len(targets) if targets else 0}")
|
|
|
+
|
|
|
if targets:
|
|
|
logger.info(f"[顺序模式] 检测到 {len(targets)} 个目标,开始顺序抓拍")
|
|
|
|
|
|
@@ -1695,8 +1712,16 @@ class SequentialCoordinator(AsyncCoordinator):
|
|
|
if self._enable_paired_saving and self._paired_saver is not None:
|
|
|
self._create_detection_batch(frame, detections, frame_size)
|
|
|
|
|
|
+ # 【关键修复】切换到抓拍状态后立即清空 tracking_targets
|
|
|
+ # 防止后续检测再次获取到同一批目标
|
|
|
+ with self.targets_lock:
|
|
|
+ self.tracking_targets.clear()
|
|
|
+ logger.info("[顺序模式] 已清空跟踪目标,防止重复抓拍")
|
|
|
+
|
|
|
# 切换到抓拍状态
|
|
|
self._start_capture_sequence(targets)
|
|
|
+ else:
|
|
|
+ logger.warning(f"[顺序模式] 有效目标为空,跳过抓拍")
|
|
|
else:
|
|
|
# 未检测到人员
|
|
|
if current_time - last_no_detect_log_time >= no_detect_log_interval:
|
|
|
@@ -1777,6 +1802,11 @@ class SequentialCoordinator(AsyncCoordinator):
|
|
|
targets = self._batch_targets.copy()
|
|
|
current_idx = self._current_capture_index
|
|
|
batch_size = self._capture_batch_size
|
|
|
+ batch_id = self._capture_batch_id
|
|
|
+
|
|
|
+ # 【调试日志】详细输出抓拍状态
|
|
|
+ logger.info(f"[顺序模式] 执行抓拍: idx={current_idx}, batch_size={batch_size}, "
|
|
|
+ f"targets_len={len(targets)}, batch_id={batch_id}")
|
|
|
|
|
|
# 使用保存的批次大小进行检查,而不是 len(targets)
|
|
|
if current_idx >= batch_size:
|
|
|
@@ -1785,6 +1815,14 @@ class SequentialCoordinator(AsyncCoordinator):
|
|
|
self._set_capture_state('returning')
|
|
|
return
|
|
|
|
|
|
+
|
|
|
+ # 【安全检查】确保 targets 有足够的数据
|
|
|
+ if current_idx >= len(targets):
|
|
|
+ logger.warning(f"[顺序模式] 索引越界: idx={current_idx} >= targets_len={len(targets)}, "
|
|
|
+ f"batch_size={batch_size}。可能批次信息不一致!")
|
|
|
+ self._set_capture_state('returning')
|
|
|
+ return
|
|
|
+
|
|
|
# 获取当前目标
|
|
|
target = targets[current_idx]
|
|
|
x_ratio, y_ratio = target.position
|