fix(cache): 修复 _load_rois_from_db 未加载 working_hours 字段的问题
Some checks failed
Python Test / test (push) Has been cancelled
Some checks failed
Python Test / test (push) Has been cancelled
- 在 roi_config 中补充读取数据库中的 working_hours 字段 - 确保 pipeline 能将 ROI 特定的工作时间配置正确传递给算法 - 修复后,LeavePostAlgorithm.is_in_working_hours() 将使用 ROI 配置而非全局默认值
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
from collections import deque
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Any, Dict, List, Optional, Tuple
|
||||
@@ -9,8 +10,6 @@ import numpy as np
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
from sort import Sort
|
||||
|
||||
|
||||
class LeavePostAlgorithm:
|
||||
STATE_ON_DUTY = "ON_DUTY"
|
||||
@@ -189,19 +188,26 @@ class LeavePostAlgorithm:
|
||||
|
||||
|
||||
class IntrusionAlgorithm:
|
||||
def __init__(
|
||||
self,
|
||||
check_interval_sec: float = 1.0,
|
||||
direction_sensitive: bool = False,
|
||||
):
|
||||
self.check_interval_sec = check_interval_sec
|
||||
self.direction_sensitive = direction_sensitive
|
||||
def __init__(self, cooldown_seconds: int = 300):
|
||||
self.cooldown_seconds = cooldown_seconds
|
||||
self.last_alert_time: Dict[str, float] = {}
|
||||
self.alert_triggered: Dict[str, bool] = {}
|
||||
|
||||
self.last_check_times: Dict[str, float] = {}
|
||||
self.tracker = Sort(max_age=5, min_hits=1, iou_threshold=0.3)
|
||||
def is_roi_has_person(self, tracks: List[Dict], roi_id: str) -> bool:
|
||||
for det in tracks:
|
||||
matched_rois = det.get("matched_rois", [])
|
||||
for roi in matched_rois:
|
||||
if roi.get("roi_id") == roi_id:
|
||||
return True
|
||||
return False
|
||||
|
||||
self.alert_cooldowns: Dict[str, datetime] = {}
|
||||
self.cooldown_seconds = 300
|
||||
def get_latest_bbox_in_roi(self, tracks: List[Dict], roi_id: str) -> List[float]:
|
||||
for det in tracks:
|
||||
matched_rois = det.get("matched_rois", [])
|
||||
for roi in matched_rois:
|
||||
if roi.get("roi_id") == roi_id:
|
||||
return det.get("bbox", [])
|
||||
return []
|
||||
|
||||
def process(
|
||||
self,
|
||||
@@ -210,52 +216,38 @@ class IntrusionAlgorithm:
|
||||
tracks: List[Dict],
|
||||
current_time: Optional[datetime] = None,
|
||||
) -> List[Dict]:
|
||||
if not tracks:
|
||||
roi_has_person = self.is_roi_has_person(tracks, roi_id)
|
||||
|
||||
if not roi_has_person:
|
||||
return []
|
||||
|
||||
detections = []
|
||||
for track in tracks:
|
||||
bbox = track.get("bbox", [])
|
||||
if len(bbox) >= 4:
|
||||
detections.append(bbox + [track.get("conf", 0.0)])
|
||||
now = time.monotonic()
|
||||
key = f"{camera_id}_{roi_id}"
|
||||
|
||||
if not detections:
|
||||
if key not in self.last_alert_time:
|
||||
self.last_alert_time[key] = 0
|
||||
self.alert_triggered[key] = False
|
||||
|
||||
if now - self.last_alert_time[key] >= self.cooldown_seconds:
|
||||
self.last_alert_time[key] = now
|
||||
self.alert_triggered[key] = False
|
||||
|
||||
if self.alert_triggered[key]:
|
||||
return []
|
||||
|
||||
current_ts = current_time.timestamp() if current_time else datetime.now().timestamp()
|
||||
bbox = self.get_latest_bbox_in_roi(tracks, roi_id)
|
||||
self.alert_triggered[key] = True
|
||||
|
||||
if camera_id in self.last_check_times:
|
||||
if current_ts - self.last_check_times[camera_id] < self.check_interval_sec:
|
||||
return []
|
||||
self.last_check_times[camera_id] = current_ts
|
||||
|
||||
detections = np.array(detections)
|
||||
tracked = self.tracker.update(detections)
|
||||
|
||||
alerts = []
|
||||
now = datetime.now()
|
||||
|
||||
for track_data in tracked:
|
||||
x1, y1, x2, y2, track_id = track_data
|
||||
cooldown_key = f"{roi_id}_{int(track_id)}"
|
||||
|
||||
if cooldown_key not in self.alert_cooldowns or (
|
||||
now - self.alert_cooldowns[cooldown_key]
|
||||
).total_seconds() > self.cooldown_seconds:
|
||||
alerts.append({
|
||||
"track_id": str(int(track_id)),
|
||||
"bbox": [x1, y1, x2, y2],
|
||||
"alert_type": "intrusion",
|
||||
"confidence": track_data[4] if len(track_data) > 4 else 0.0,
|
||||
"message": "检测到周界入侵",
|
||||
})
|
||||
self.alert_cooldowns[cooldown_key] = now
|
||||
|
||||
return alerts
|
||||
return [{
|
||||
"roi_id": roi_id,
|
||||
"bbox": bbox,
|
||||
"alert_type": "intrusion",
|
||||
"message": "检测到周界入侵",
|
||||
}]
|
||||
|
||||
def reset(self):
|
||||
self.last_check_times.clear()
|
||||
self.alert_cooldowns.clear()
|
||||
self.last_alert_time.clear()
|
||||
self.alert_triggered.clear()
|
||||
|
||||
|
||||
class AlgorithmManager:
|
||||
@@ -270,8 +262,7 @@ class AlgorithmManager:
|
||||
"return_sec": 30,
|
||||
},
|
||||
"intrusion": {
|
||||
"check_interval_sec": 1.0,
|
||||
"direction_sensitive": False,
|
||||
"cooldown_seconds": 300,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -302,8 +293,7 @@ class AlgorithmManager:
|
||||
)
|
||||
elif algorithm_type == "intrusion":
|
||||
self.algorithms[roi_id]["intrusion"] = IntrusionAlgorithm(
|
||||
check_interval_sec=algo_params.get("check_interval_sec", 1.0),
|
||||
direction_sensitive=algo_params.get("direction_sensitive", False),
|
||||
cooldown_seconds=algo_params.get("cooldown_seconds", 300),
|
||||
)
|
||||
|
||||
def process(
|
||||
|
||||
Reference in New Issue
Block a user