去除用秒判断,通过帧率判断,菜名不一样,但像同盘,就过滤
This commit is contained in:
parent
678706454a
commit
e0a4f85f59
|
|
@ -118,8 +118,9 @@ DISH_LIVE_MOTION_SIM_WITH_ORDER = float(os.environ.get('DISH_LIVE_MOTION_SIM_WIT
|
|||
DISH_LIVE_ORDER_DEBOUNCE_SECONDS = float(os.environ.get('DISH_LIVE_ORDER_DEBOUNCE_SECONDS', '2'))
|
||||
# 无餐盘持续该秒数后清场解锁,允许下一盘(含相同菜名)重新存图/上报
|
||||
DISH_LIVE_ORDER_CLEAR_HOLD_SECONDS = float(os.environ.get('DISH_LIVE_ORDER_CLEAR_HOLD_SECONDS', '1.5'))
|
||||
# 短时同场景去重:窗口内即使个别菜名识别不同,只要检测框布局相近也视为同一单(不重复上报)
|
||||
DISH_LIVE_ORDER_SAME_SCENE_SECONDS = float(os.environ.get('DISH_LIVE_ORDER_SAME_SCENE_SECONDS', '1.5'))
|
||||
# 同场景去重:按预览帧计数(约 25fps,默认 40 帧 ≈ 1.6s)。
|
||||
# 窗口内即使个别菜名不同,只要检测框布局相近也视为同一单(不重复上报)
|
||||
DISH_LIVE_ORDER_SAME_SCENE_FRAMES = int(os.environ.get('DISH_LIVE_ORDER_SAME_SCENE_FRAMES', '40'))
|
||||
# 框匹配 IoU 阈值;匹配对数占比阈值(0~1)
|
||||
DISH_LIVE_ORDER_LAYOUT_IOU = float(os.environ.get('DISH_LIVE_ORDER_LAYOUT_IOU', '0.40'))
|
||||
DISH_LIVE_ORDER_LAYOUT_MATCH_RATIO = float(os.environ.get('DISH_LIVE_ORDER_LAYOUT_MATCH_RATIO', '0.70'))
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ from dao.settings import (
|
|||
DISH_LIVE_MOTION_SIM_WITH_ORDER,
|
||||
DISH_LIVE_ORDER_DEBOUNCE_SECONDS,
|
||||
DISH_LIVE_ORDER_CLEAR_HOLD_SECONDS,
|
||||
DISH_LIVE_ORDER_SAME_SCENE_SECONDS,
|
||||
DISH_LIVE_ORDER_SAME_SCENE_FRAMES,
|
||||
DISH_LIVE_ORDER_LAYOUT_IOU,
|
||||
DISH_LIVE_ORDER_LAYOUT_MATCH_RATIO,
|
||||
DISH_STREAM_RECORD_ENABLED,
|
||||
|
|
@ -157,11 +157,13 @@ class BaseDishApp(PendingLearningUIMixin):
|
|||
self._live_stable_snapshot = None # 稳定期间保留的 dishes,供写入
|
||||
self._last_reported_sig = None # 实时上报去重:相同菜名集合只报一次
|
||||
self._last_order_dish_sig = None # 仅菜名签名:菜未变不重复存图/统计
|
||||
self._last_order_boxes = None # 上一单检测框,用于短时同场景去重(忽略菜名抖动)
|
||||
self._last_order_boxes = None # 上一单检测框,用于同场景去重(忽略菜名抖动)
|
||||
self._last_order_at = 0.0
|
||||
self._last_order_preview_seq = None # 上一单对应的预览帧序号
|
||||
self._preview_frame_seq = 0 # 预览成功取帧累计(用于按帧去重)
|
||||
self._order_clear_since = None # 无盘连续计时起点
|
||||
self._order_clear_hold = float(DISH_LIVE_ORDER_CLEAR_HOLD_SECONDS)
|
||||
self._order_same_scene_seconds = float(DISH_LIVE_ORDER_SAME_SCENE_SECONDS)
|
||||
self._order_same_scene_frames = max(0, int(DISH_LIVE_ORDER_SAME_SCENE_FRAMES))
|
||||
self._order_layout_iou = float(DISH_LIVE_ORDER_LAYOUT_IOU)
|
||||
self._order_layout_match_ratio = float(DISH_LIVE_ORDER_LAYOUT_MATCH_RATIO)
|
||||
self._last_detect_fp = None # 识别后锚点指纹(静止等待运动;仅餐盘区域)
|
||||
|
|
@ -2053,6 +2055,7 @@ class BaseDishApp(PendingLearningUIMixin):
|
|||
self._last_order_dish_sig = None
|
||||
self._last_order_boxes = None
|
||||
self._last_order_at = 0.0
|
||||
self._last_order_preview_seq = None
|
||||
self._last_reported_sig = None
|
||||
|
||||
def _note_order_scene_busy(self):
|
||||
|
|
@ -2140,12 +2143,13 @@ class BaseDishApp(PendingLearningUIMixin):
|
|||
self._last_order_dish_sig = order_sig
|
||||
self._last_order_boxes = self._extract_order_boxes(dishes)
|
||||
self._last_order_at = time.time()
|
||||
self._last_order_preview_seq = int(getattr(self, "_preview_frame_seq", 0) or 0)
|
||||
|
||||
def _should_record_new_order(self, dishes):
|
||||
"""菜品未变 / 短时同场景 → 不存图、不重新统计订单。
|
||||
"""菜品未变 / 同场景(按预览帧) → 不存图、不重新统计订单。
|
||||
|
||||
- 菜名组合相同:始终视为同一单(直到清场)
|
||||
- 短时窗口内菜名略有不同,但检测框布局相近:仍视为同一盘(剔除重复上报)
|
||||
- 上报后 N 个预览帧内,菜名略有不同但检测框布局相近:仍视为同一盘
|
||||
清场解锁后 `_last_order_dish_sig` 已被清空,相同菜名可再报一单。
|
||||
"""
|
||||
sig = self._order_dish_signature(dishes)
|
||||
|
|
@ -2165,16 +2169,22 @@ class BaseDishApp(PendingLearningUIMixin):
|
|||
print("[live] 菜品未变,跳过存图/订单统计")
|
||||
return False, sig
|
||||
|
||||
# 菜名不同:短时内若框布局仍像同一盘,也不重复上报
|
||||
same_scene_s = float(
|
||||
getattr(self, "_order_same_scene_seconds", DISH_LIVE_ORDER_SAME_SCENE_SECONDS) or 1.5
|
||||
# 菜名不同:按预览帧窗口 + 框布局判断是否同一盘
|
||||
same_frames = int(
|
||||
getattr(self, "_order_same_scene_frames", DISH_LIVE_ORDER_SAME_SCENE_FRAMES) or 0
|
||||
)
|
||||
if last_at and same_scene_s > 0 and (now - last_at) <= same_scene_s:
|
||||
last_seq = getattr(self, "_last_order_preview_seq", None)
|
||||
cur_seq = int(getattr(self, "_preview_frame_seq", 0) or 0)
|
||||
if (
|
||||
same_frames > 0
|
||||
and last_seq is not None
|
||||
and (cur_seq - int(last_seq)) <= same_frames
|
||||
):
|
||||
last_boxes = getattr(self, "_last_order_boxes", None)
|
||||
if self._order_layouts_similar(dishes, last_boxes):
|
||||
print(
|
||||
f"[live] {same_scene_s:g}s 内同场景(框布局相近,忽略菜名差异),"
|
||||
f"跳过重复上报"
|
||||
f"[live] {same_frames} 帧内同场景(框布局相近,忽略菜名差异),"
|
||||
f"跳过重复上报 seq={cur_seq - int(last_seq)}/{same_frames}"
|
||||
)
|
||||
return False, sig
|
||||
return True, sig
|
||||
|
|
@ -2532,6 +2542,7 @@ class BaseDishApp(PendingLearningUIMixin):
|
|||
try:
|
||||
frame = self.grab_preview_frame()
|
||||
if frame is not None:
|
||||
self._preview_frame_seq = int(getattr(self, "_preview_frame_seq", 0) or 0) + 1
|
||||
with self._live_lock:
|
||||
self._latest_frame = frame
|
||||
self.show_preview_frame(frame)
|
||||
|
|
|
|||
Loading…
Reference in New Issue