同步算法修改
This commit is contained in:
@@ -79,7 +79,7 @@ class KadianDetector:
|
||||
|
||||
# 1. 业务判定时间阈值
|
||||
self.TIME_THRESHOLD_ONLY_ONE = 3.0 # 单人单检判定时长
|
||||
self.TIME_THRESHOLD_NOBODY = 2.0 # 无人检查判定时长
|
||||
self.TIME_THRESHOLD_NOBODY = 3.0 # 无人检查判定时长
|
||||
|
||||
# 后备箱检查判定阈值
|
||||
self.TIME_THRESHOLD_TRUNK_OPEN = 0.5
|
||||
@@ -129,6 +129,15 @@ class KadianDetector:
|
||||
logger.info(f" 制服合规恢复缓冲帧数: {self.frame_buffer_uniform} 帧")
|
||||
logger.info(f" 判定 'Too Fast' (视为Nobody) 最小停留: {self.frame_thresh_car_min_duration} 帧")
|
||||
|
||||
self.onlyone_counter = 0
|
||||
self.onlyone_lost_counter = 0
|
||||
self.onlyone_buffer_limit = self.frame_buffer_limit_person # 10帧(1秒)
|
||||
self.onlyone_thresh = self.frame_thresh_one # 30帧(3秒)
|
||||
|
||||
self.nobody_counter = 0
|
||||
self.nobody_present_counter = 0
|
||||
self.nobody_buffer_limit = 10 # 10帧(1秒)
|
||||
self.nobody_thresh = self.frame_thresh_nobody # 20帧(2秒)
|
||||
|
||||
self.current_frame_idx = 0
|
||||
self.cnt_frame_one_person = 0
|
||||
@@ -161,21 +170,14 @@ class KadianDetector:
|
||||
用于 pointPolygonTest 和 polylines
|
||||
"""
|
||||
if self.roi_points is None:
|
||||
# 使用默认相对坐标
|
||||
default_rel = np.array([
|
||||
[0.15, 0.01],
|
||||
[0.45, 0.01],
|
||||
[0.95, 0.95],
|
||||
[0.35, 0.95]
|
||||
], dtype=np.float64)
|
||||
roi_abs = default_rel * np.array([frame_width, frame_height])
|
||||
raise ValueError("ROI points must be provided; cannot be None.")
|
||||
|
||||
if self.roi_points.max() <= 1.0:
|
||||
# 相对坐标 → 转换为绝对
|
||||
roi_abs = self.roi_points * np.array([frame_width, frame_height])
|
||||
else:
|
||||
if self.roi_points.max() <= 1.0:
|
||||
# 相对坐标 → 转换为绝对
|
||||
roi_abs = self.roi_points * np.array([frame_width, frame_height])
|
||||
else:
|
||||
# 绝对坐标,直接使用
|
||||
roi_abs = self.roi_points.copy()
|
||||
# 绝对坐标,直接使用
|
||||
roi_abs = self.roi_points.copy()
|
||||
|
||||
# 强制转为 int32(关键!解决 OpenCV 断言错误)
|
||||
return roi_abs.astype(np.int32)
|
||||
@@ -529,34 +531,87 @@ class KadianDetector:
|
||||
# ==========================================
|
||||
# 9. 业务逻辑判定 (Only One / Nobody)
|
||||
# ==========================================
|
||||
status_text = ""
|
||||
# status_text = ""
|
||||
#
|
||||
# if effective_car_count > 0:
|
||||
# # --- Only One ---
|
||||
# if current_roi_person_count == 1:
|
||||
# self.cnt_frame_one_person += 1
|
||||
# self.cnt_missing_buffer_person = 0
|
||||
# self.cnt_frame_nobody = 0
|
||||
#
|
||||
# # --- Nobody ---
|
||||
# elif current_roi_person_count == 0:
|
||||
# if self.cnt_frame_one_person > 0 and self.cnt_missing_buffer_person < self.frame_buffer_limit_person:
|
||||
# self.cnt_frame_one_person += 1
|
||||
# self.cnt_missing_buffer_person += 1
|
||||
# self.cnt_frame_nobody = 0
|
||||
# status_text = f"Person Buffer ({self.cnt_missing_buffer_person}/{self.frame_buffer_limit_person})"
|
||||
# else:
|
||||
# self.cnt_frame_one_person = 0
|
||||
# self.cnt_missing_buffer_person = 0
|
||||
# self.cnt_frame_nobody += 1
|
||||
# else:
|
||||
# self.cnt_frame_one_person = 0
|
||||
# self.cnt_missing_buffer_person = 0
|
||||
# self.cnt_frame_nobody = 0
|
||||
# else:
|
||||
# self.cnt_frame_one_person = 0
|
||||
# self.cnt_missing_buffer_person = 0
|
||||
# self.cnt_frame_nobody = 0
|
||||
|
||||
if effective_car_count > 0:
|
||||
# --- Only One ---
|
||||
if current_roi_person_count == 1:
|
||||
self.cnt_frame_one_person += 1
|
||||
self.cnt_missing_buffer_person = 0
|
||||
self.cnt_frame_nobody = 0
|
||||
# ==========================================
|
||||
# 9. 业务逻辑判定 (Only One / Nobody) - 重构版
|
||||
# ==========================================
|
||||
if effective_car_count >= 0: # 只要没人就检测,不用等到来了车再检测
|
||||
# ----- 定义条件 -----
|
||||
onlyone_condition = (current_roi_person_count == 1 and self.pose_person_count == 1)
|
||||
nobody_condition = (current_roi_person_count == 0 and self.pose_person_count == 0)
|
||||
|
||||
# --- Nobody ---
|
||||
elif current_roi_person_count == 0:
|
||||
if self.cnt_frame_one_person > 0 and self.cnt_missing_buffer_person < self.frame_buffer_limit_person:
|
||||
self.cnt_frame_one_person += 1
|
||||
self.cnt_missing_buffer_person += 1
|
||||
self.cnt_frame_nobody = 0
|
||||
status_text = f"Person Buffer ({self.cnt_missing_buffer_person}/{self.frame_buffer_limit_person})"
|
||||
else:
|
||||
self.cnt_frame_one_person = 0
|
||||
self.cnt_missing_buffer_person = 0
|
||||
self.cnt_frame_nobody += 1
|
||||
# ----- Onlyone 计数器更新 -----
|
||||
if onlyone_condition:
|
||||
self.onlyone_counter += 1
|
||||
self.onlyone_lost_counter = 0
|
||||
else:
|
||||
self.cnt_frame_one_person = 0
|
||||
self.cnt_missing_buffer_person = 0
|
||||
self.cnt_frame_nobody = 0
|
||||
if self.onlyone_counter > 0:
|
||||
self.onlyone_lost_counter += 1
|
||||
if self.onlyone_lost_counter > self.onlyone_buffer_limit:
|
||||
self.onlyone_counter = 0
|
||||
self.onlyone_lost_counter = 0
|
||||
# 没有累积的 Onlyone 则不做任何事
|
||||
|
||||
# ----- Nobody 计数器更新 -----
|
||||
if nobody_condition:
|
||||
self.nobody_counter += 1
|
||||
self.nobody_present_counter = 0
|
||||
else:
|
||||
if self.nobody_counter > 0:
|
||||
self.nobody_present_counter += 1
|
||||
if self.nobody_present_counter > self.nobody_buffer_limit:
|
||||
self.nobody_counter = 0
|
||||
self.nobody_present_counter = 0
|
||||
# 没有累积的 Nobody 则不做任何事
|
||||
|
||||
# ----- 准备显示状态文字(可选)-----
|
||||
if self.onlyone_counter > 0:
|
||||
if onlyone_condition:
|
||||
status_text = f"OnlyOne: {self.onlyone_counter}/{self.onlyone_thresh}"
|
||||
else:
|
||||
status_text = f"OnlyOne Lost: {self.onlyone_lost_counter}/{self.onlyone_buffer_limit}"
|
||||
elif self.nobody_counter > 0:
|
||||
if nobody_condition:
|
||||
status_text = f"Nobody: {self.nobody_counter}/{self.nobody_thresh}"
|
||||
else:
|
||||
status_text = f"Nobody Interrupted: {self.nobody_present_counter}/{self.nobody_buffer_limit}"
|
||||
else:
|
||||
status_text = ""
|
||||
|
||||
else:
|
||||
self.cnt_frame_one_person = 0
|
||||
self.cnt_missing_buffer_person = 0
|
||||
self.cnt_frame_nobody = 0
|
||||
# 无活跃车辆,清零所有计数器
|
||||
self.onlyone_counter = 0
|
||||
self.onlyone_lost_counter = 0
|
||||
self.nobody_counter = 0
|
||||
self.nobody_present_counter = 0
|
||||
|
||||
# ==========================================
|
||||
# 10. 显示报警 (UI分层优化)
|
||||
@@ -581,25 +636,37 @@ class KadianDetector:
|
||||
# 第一层:实时状态 (Real-time Status)
|
||||
# ------------------------------------------------
|
||||
# A. 显示 Only One
|
||||
if self.cnt_frame_one_person >= self.frame_thresh_one:
|
||||
current_frame_alerts.append(
|
||||
{
|
||||
'time': current_time_sec,
|
||||
'action': "Only One",
|
||||
}
|
||||
)
|
||||
self.draw_alert(frame, "Only One", (0, 255, 255), status_text, offset_y=alert_offset)
|
||||
# if self.cnt_frame_one_person >= self.frame_thresh_one:
|
||||
# current_frame_alerts.append(
|
||||
# {
|
||||
# 'time': current_time_sec,
|
||||
# 'action': "Only One",
|
||||
# }
|
||||
# )
|
||||
# self.draw_alert(frame, "Only One", (0, 255, 255), status_text, offset_y=alert_offset)
|
||||
# alert_offset += 100
|
||||
#
|
||||
# # B. 显示 Nobody (实时状态)
|
||||
# elif self.cnt_frame_nobody >= self.frame_thresh_nobody:
|
||||
# current_frame_alerts.append(
|
||||
# {
|
||||
# 'time': current_time_sec,
|
||||
# 'action': "Nobody",
|
||||
# }
|
||||
# )
|
||||
# self.draw_alert(frame, "Nobody", (0, 0, 255), offset_y=alert_offset)
|
||||
# alert_offset += 100
|
||||
|
||||
# A. 显示 Only One(当累积帧数达到阈值时)
|
||||
if self.onlyone_counter >= self.onlyone_thresh:
|
||||
current_frame_alerts.append({'time': current_time_sec, 'action': "Only One"})
|
||||
self.draw_alert(frame, "Only One", (0, 255, 255), None, offset_y=alert_offset)
|
||||
alert_offset += 100
|
||||
|
||||
# B. 显示 Nobody (实时状态)
|
||||
elif self.cnt_frame_nobody >= self.frame_thresh_nobody:
|
||||
current_frame_alerts.append(
|
||||
{
|
||||
'time': current_time_sec,
|
||||
'action': "Nobody",
|
||||
}
|
||||
)
|
||||
self.draw_alert(frame, "Nobody", (0, 0, 255), offset_y=alert_offset)
|
||||
# B. 显示 Nobody(当累积帧数达到阈值时)
|
||||
elif self.nobody_counter >= self.nobody_thresh:
|
||||
current_frame_alerts.append({'time': current_time_sec, 'action': "Nobody"})
|
||||
self.draw_alert(frame, "Nobody", (0, 0, 255), None, offset_y=alert_offset)
|
||||
alert_offset += 100
|
||||
|
||||
# C. 显示 Trunk Checked (在车辆存活期间)
|
||||
@@ -619,28 +686,28 @@ class KadianDetector:
|
||||
if self.phone_alert_active:
|
||||
# 可以显示检测的持续时间
|
||||
duration_seconds = self.phone_detection_frames / self.fps
|
||||
sub_text = f"Detected for {duration_seconds:.1f}s"
|
||||
#sub_text = f"Detected for {duration_seconds:.1f}s"
|
||||
current_frame_alerts.append(
|
||||
{
|
||||
'time': current_time_sec,
|
||||
'action': "Playing Phone",
|
||||
}
|
||||
)
|
||||
self.draw_alert(frame, "Playing Phone", (255, 0, 0), sub_text, offset_y=alert_offset)
|
||||
self.draw_alert(frame, "Playing Phone", (255, 0, 0), None, offset_y=alert_offset)
|
||||
alert_offset += 100
|
||||
|
||||
# E. 新增:显示 Unvaild Uniform!!
|
||||
if self.uniform_alert_active:
|
||||
# 显示具体数量差异
|
||||
diff = self.pose_person_count - current_roi_person_count
|
||||
sub_text = f"Missing {diff} uniform(s)"
|
||||
#sub_text = f"Missing {diff} uniform(s)"
|
||||
current_frame_alerts.append(
|
||||
{
|
||||
'time': current_time_sec,
|
||||
'action': "Unvaild Uniform!!",
|
||||
}
|
||||
)
|
||||
self.draw_alert(frame, "Unvaild Uniform!!", (255, 165, 0), sub_text, offset_y=alert_offset)
|
||||
self.draw_alert(frame, "Unvaild Uniform!!", (255, 165, 0), None, offset_y=alert_offset)
|
||||
alert_offset += 100
|
||||
|
||||
# 第二层:离场违规 (Post-Event Alerts)
|
||||
@@ -663,18 +730,18 @@ class KadianDetector:
|
||||
self.draw_alert(frame, alert_text, (0, 0, 255), offset_y=alert_offset)
|
||||
alert_offset += 100
|
||||
|
||||
# G. 显示 Nobody (离场结果)
|
||||
# G. 显示 Ignore (离场结果)
|
||||
expired_fast_alerts = [cid for cid, end_frame in self.fast_pass_alerts.items() if
|
||||
self.current_frame_idx > end_frame]
|
||||
for cid in expired_fast_alerts:
|
||||
del self.fast_pass_alerts[cid]
|
||||
|
||||
if len(self.fast_pass_alerts) > 0:
|
||||
alert_text = f"Nobody (ID:{list(self.fast_pass_alerts.keys())})"
|
||||
alert_text = f"Ignore: (ID:{list(self.fast_pass_alerts.keys())})"
|
||||
current_frame_alerts.append(
|
||||
{
|
||||
'time': current_time_sec,
|
||||
'action': "Nobody",
|
||||
'action': "Ignore",
|
||||
}
|
||||
)
|
||||
self.draw_alert(frame, alert_text, (0, 0, 255), offset_y=alert_offset)
|
||||
|
||||
Reference in New Issue
Block a user