|
@@ -1591,6 +1591,10 @@ class SequentialCoordinator(AsyncCoordinator):
|
|
|
self._batch_targets_lock = threading.Lock()
|
|
self._batch_targets_lock = threading.Lock()
|
|
|
self._current_capture_index = 0
|
|
self._current_capture_index = 0
|
|
|
|
|
|
|
|
|
|
+ # 【关键修复】保存当前批次的完整信息,防止抓拍过程中被覆盖
|
|
|
|
|
+ self._capture_batch_id: Optional[str] = None
|
|
|
|
|
+ self._capture_batch_size: int = 0
|
|
|
|
|
+
|
|
|
# 抓拍完成事件(用于同步)
|
|
# 抓拍完成事件(用于同步)
|
|
|
self._capture_done_event = threading.Event()
|
|
self._capture_done_event = threading.Event()
|
|
|
|
|
|
|
@@ -1753,8 +1757,17 @@ class SequentialCoordinator(AsyncCoordinator):
|
|
|
def _start_capture_sequence(self, targets: List[TrackingTarget]):
|
|
def _start_capture_sequence(self, targets: List[TrackingTarget]):
|
|
|
"""开始顺序抓拍序列"""
|
|
"""开始顺序抓拍序列"""
|
|
|
with self._batch_targets_lock:
|
|
with self._batch_targets_lock:
|
|
|
- self._batch_targets = targets.copy()
|
|
|
|
|
|
|
+ # 【关键修复】先清空再赋值,防止累积
|
|
|
|
|
+ old_count = len(self._batch_targets)
|
|
|
|
|
+ self._batch_targets = targets.copy() # 直接替换,不追加
|
|
|
self._current_capture_index = 0
|
|
self._current_capture_index = 0
|
|
|
|
|
+
|
|
|
|
|
+ # 【关键修复】保存批次信息,防止抓拍过程中被新批次覆盖
|
|
|
|
|
+ self._capture_batch_id = self._current_batch_id
|
|
|
|
|
+ self._capture_batch_size = len(targets)
|
|
|
|
|
+
|
|
|
|
|
+ logger.info(f"[顺序模式] 开始抓拍序列: {old_count} -> {len(self._batch_targets)} 个目标, "
|
|
|
|
|
+ f"批次ID={self._capture_batch_id}")
|
|
|
|
|
|
|
|
self._set_capture_state('capturing')
|
|
self._set_capture_state('capturing')
|
|
|
|
|
|
|
@@ -1763,10 +1776,12 @@ class SequentialCoordinator(AsyncCoordinator):
|
|
|
with self._batch_targets_lock:
|
|
with self._batch_targets_lock:
|
|
|
targets = self._batch_targets.copy()
|
|
targets = self._batch_targets.copy()
|
|
|
current_idx = self._current_capture_index
|
|
current_idx = self._current_capture_index
|
|
|
|
|
+ batch_size = self._capture_batch_size
|
|
|
|
|
|
|
|
- if current_idx >= len(targets):
|
|
|
|
|
|
|
+ # 使用保存的批次大小进行检查,而不是 len(targets)
|
|
|
|
|
+ if current_idx >= batch_size:
|
|
|
# 所有目标已抓拍完成
|
|
# 所有目标已抓拍完成
|
|
|
- logger.info("[顺序模式] 所有目标抓拍完成")
|
|
|
|
|
|
|
+ logger.info(f"[顺序模式] 所有目标抓拍完成: {current_idx}/{batch_size}")
|
|
|
self._set_capture_state('returning')
|
|
self._set_capture_state('returning')
|
|
|
return
|
|
return
|
|
|
|
|
|
|
@@ -1785,13 +1800,15 @@ class SequentialCoordinator(AsyncCoordinator):
|
|
|
pan, tilt, zoom = self.ptz.calculate_ptz_position(x_ratio, y_ratio)
|
|
pan, tilt, zoom = self.ptz.calculate_ptz_position(x_ratio, y_ratio)
|
|
|
coord_type = "估算坐标"
|
|
coord_type = "估算坐标"
|
|
|
|
|
|
|
|
- # 获取批次信息
|
|
|
|
|
- batch_id = self._current_batch_id if self._enable_paired_saving else None
|
|
|
|
|
|
|
+ # 获取批次信息(使用保存的批次ID,防止被新批次覆盖)
|
|
|
|
|
+ with self._batch_targets_lock:
|
|
|
|
|
+ batch_id = self._capture_batch_id if self._enable_paired_saving else None
|
|
|
|
|
+ batch_size = self._capture_batch_size
|
|
|
person_index = current_idx # 使用当前索引作为人员序号
|
|
person_index = current_idx # 使用当前索引作为人员序号
|
|
|
|
|
|
|
|
- logger.info(f"[顺序模式] 抓拍目标 {current_idx + 1}/{len(targets)}: "
|
|
|
|
|
|
|
+ logger.info(f"[顺序模式] 抓拍目标 {current_idx + 1}/{batch_size}: "
|
|
|
f"位置=({x_ratio:.3f}, {y_ratio:.3f}) -> "
|
|
f"位置=({x_ratio:.3f}, {y_ratio:.3f}) -> "
|
|
|
- f"PTZ=({pan:.1f}°, {tilt:.1f}°, zoom={zoom}) [{coord_type}]")
|
|
|
|
|
|
|
+ f"PTZ=({pan:.1f}°, {tilt:.1f}°, zoom={zoom}) [{coord_type}], 批次={batch_id}")
|
|
|
|
|
|
|
|
# 执行PTZ移动
|
|
# 执行PTZ移动
|
|
|
self._set_state(TrackingState.TRACKING)
|
|
self._set_state(TrackingState.TRACKING)
|
|
@@ -1868,6 +1885,9 @@ class SequentialCoordinator(AsyncCoordinator):
|
|
|
with self._batch_targets_lock:
|
|
with self._batch_targets_lock:
|
|
|
self._batch_targets = []
|
|
self._batch_targets = []
|
|
|
self._current_capture_index = 0
|
|
self._current_capture_index = 0
|
|
|
|
|
+ # 【关键修复】清空保存的批次信息
|
|
|
|
|
+ self._capture_batch_id = None
|
|
|
|
|
+ self._capture_batch_size = 0
|
|
|
|
|
|
|
|
# 【关键修复】清空跟踪目标,防止跨帧累积
|
|
# 【关键修复】清空跟踪目标,防止跨帧累积
|
|
|
with self.targets_lock:
|
|
with self.targets_lock:
|