|
|
@@ -1506,14 +1506,14 @@ class AsyncCoordinator(Coordinator):
|
|
|
logger.error(f"[AutoZoom] 自动对焦异常: {e}")
|
|
|
return initial_zoom
|
|
|
|
|
|
- def _get_clear_ptz_frame(self, max_attempts: int = 5, wait_interval: float = 0.1) -> Optional[np.ndarray]:
|
|
|
+ def _get_clear_ptz_frame(self, max_attempts: int = 8, wait_interval: float = 0.15) -> Optional[np.ndarray]:
|
|
|
"""
|
|
|
获取清晰的球机画面
|
|
|
尝试多次获取,丢弃模糊/过渡帧
|
|
|
|
|
|
Args:
|
|
|
- max_attempts: 最大尝试次数
|
|
|
- wait_interval: 每次等待间隔
|
|
|
+ max_attempts: 最大尝试次数(默认8次)
|
|
|
+ wait_interval: 每次等待间隔(默认0.15秒)
|
|
|
|
|
|
Returns:
|
|
|
清晰的球机帧或 None
|
|
|
@@ -1521,6 +1521,12 @@ class AsyncCoordinator(Coordinator):
|
|
|
best_frame = None
|
|
|
best_score = -1
|
|
|
|
|
|
+ # 【改进】先刷新缓冲区,丢弃旧帧
|
|
|
+ logger.debug("[帧获取] 刷新RTSP缓冲区...")
|
|
|
+ for _ in range(3):
|
|
|
+ self.ptz.get_frame()
|
|
|
+ time.sleep(0.05)
|
|
|
+
|
|
|
for i in range(max_attempts):
|
|
|
frame = self.ptz.get_frame()
|
|
|
if frame is not None:
|
|
|
@@ -1528,16 +1534,24 @@ class AsyncCoordinator(Coordinator):
|
|
|
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
|
|
|
laplacian_var = cv2.Laplacian(gray, cv2.CV_64F).var()
|
|
|
|
|
|
+ logger.debug(f"[帧获取] 尝试 {i+1}/{max_attempts}: 清晰度={laplacian_var:.1f}")
|
|
|
+
|
|
|
if laplacian_var > best_score:
|
|
|
best_score = laplacian_var
|
|
|
best_frame = frame.copy()
|
|
|
|
|
|
# 如果清晰度足够高,直接返回
|
|
|
- if laplacian_var > 100: # 清晰度阈值
|
|
|
+ if laplacian_var > 150: # 【提高】清晰度阈值从100提高到150
|
|
|
+ logger.info(f"[帧获取] 获取清晰帧: 尝试 {i+1} 次, 清晰度={laplacian_var:.1f}")
|
|
|
return frame
|
|
|
|
|
|
time.sleep(wait_interval)
|
|
|
|
|
|
+ if best_frame is not None:
|
|
|
+ logger.info(f"[帧获取] 返回最佳帧: 清晰度={best_score:.1f}")
|
|
|
+ else:
|
|
|
+ logger.warning("[帧获取] 未能获取有效帧")
|
|
|
+
|
|
|
return best_frame
|
|
|
|
|
|
def _mark_ptz_frame_with_detection(self, frame: np.ndarray, person_index: int) -> np.ndarray:
|
|
|
@@ -1662,8 +1676,9 @@ class SequentialCoordinator(AsyncCoordinator):
|
|
|
|
|
|
# 配置参数
|
|
|
self._capture_config = {
|
|
|
- 'ptz_stabilize_time': 1.0, # PTZ到位后稳定等待时间
|
|
|
+ 'ptz_stabilize_time': 2.5, # PTZ到位后稳定等待时间(秒)
|
|
|
'capture_wait_time': 0.5, # 抓拍等待时间
|
|
|
+ 'auto_zoom_wait_time': 1.0, # AutoZoom变焦后额外等待时间(秒)
|
|
|
'return_to_panorama': True, # 完成后是否回到全景默认位置
|
|
|
'default_pan': 0.0, # 默认pan角度
|
|
|
'default_tilt': 0.0, # 默认tilt角度
|
|
|
@@ -1932,7 +1947,10 @@ class SequentialCoordinator(AsyncCoordinator):
|
|
|
auto_zoom_result = self._auto_zoom_person(pan, tilt, zoom)
|
|
|
if auto_zoom_result != zoom:
|
|
|
final_zoom = auto_zoom_result
|
|
|
- time.sleep(0.5) # 变焦后再次等待
|
|
|
+ # 变焦后等待镜头对焦
|
|
|
+ auto_zoom_wait = self._capture_config.get('auto_zoom_wait_time', 1.0)
|
|
|
+ logger.info(f"[顺序模式] 变焦完成,等待镜头对焦 {auto_zoom_wait}s...")
|
|
|
+ time.sleep(auto_zoom_wait)
|
|
|
|
|
|
# 获取清晰的球机画面
|
|
|
ptz_frame = self._get_clear_ptz_frame()
|