拦截菜品一样,识别的未知标签不一样的,进行订单防抖,

This commit is contained in:
wanghanbo 2026-10-14 17:48:10 +08:00
parent 7299d8a766
commit 621bec63fb
2 changed files with 25 additions and 25 deletions

View File

@ -118,9 +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'))
# 同场景去重:按预览帧计数(约 25fps,默认 40 帧 ≈ 1.6s)。
# 窗口内即使个别菜名不同,只要检测框布局相近也视为同一单(不重复上报)
DISH_LIVE_ORDER_SAME_SCENE_FRAMES = int(os.environ.get('DISH_LIVE_ORDER_SAME_SCENE_FRAMES', '40'))
# 同场景去重:按预览帧计数(约 25fps,默认 60 帧 ≈ 2.4s)。
# 窗口内即使个别已知菜名不同,只要检测框布局相近也视为同一单(不重复上报)
DISH_LIVE_ORDER_SAME_SCENE_FRAMES = int(os.environ.get('DISH_LIVE_ORDER_SAME_SCENE_FRAMES', '60'))
# 框匹配 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'))

View File

@ -1992,18 +1992,23 @@ class BaseDishApp(PendingLearningUIMixin):
self._live_stable_snapshot = None
# committed_sig 保留到场景变化时再清,避免同一场景反复写入
@staticmethod
def _quantize_box(box, step=40):
if isinstance(box, (list, tuple)) and len(box) >= 4:
try:
return tuple(int(round(float(x) / float(step))) * int(step) for x in box[:4])
except Exception:
return (0, 0, 0, 0)
return (0, 0, 0, 0)
def _live_result_signature(self, dishes):
"""粗粒度签名:盘数 + 已知/未知名 + 量化框(忽略细微分数抖动)。"""
"""粗粒度签名:盘数 + 已知名/未知框(未知不用建议菜名,避免红薯↔土豆抖动)。"""
parts = []
for d in dishes or []:
box = d.get("box") or []
if isinstance(box, (list, tuple)) and len(box) >= 4:
qb = tuple(int(round(float(x) / 40.0)) * 40 for x in box[:4])
else:
qb = (0, 0, 0, 0)
qb = self._quantize_box(d.get("box"))
if d.get("is_unknown"):
sug = (d.get("suggested_category") or "").strip()[:24]
parts.append(("U", sug, qb))
# 未知只按框位置,建议名(红薯/土豆等)不参与
parts.append(("U", "", qb))
else:
name = (d.get("label") or d.get("name") or "").strip()[:24]
parts.append(("K", name, qb))
@ -2011,16 +2016,12 @@ class BaseDishApp(PendingLearningUIMixin):
return (len(parts), tuple(parts))
def _report_signature(self, dishes):
"""上报去重签名:已知 + 未知(is_unknown)菜名多重集合(不含框)。"""
"""上报去重签名:已知菜名 + 未知按量化框(建议名不参与)。"""
keys = []
for d in dishes or []:
if d.get("is_unknown"):
sug = (
d.get("suggested_name")
or d.get("suggested_category")
or "未知"
)
keys.append(("U", str(sug).strip()[:24] or "未知"))
qb = self._quantize_box(d.get("box"))
keys.append(("U", qb))
else:
name = (d.get("label") or d.get("name") or "").strip()
if name:
@ -2030,16 +2031,15 @@ class BaseDishApp(PendingLearningUIMixin):
return tuple(sorted(Counter(keys).items()))
def _order_dish_signature(self, dishes):
"""订单菜品签名:已知 + 未知组合(忽略框位置),手晃框抖不算新单。"""
"""订单菜品签名:已知按菜名;未知按框位置(忽略建议名抖动)。
例如同一未知框建议从「红薯」变成「土豆」仍视为同一单,避免 1~2 秒内双报。
"""
keys = []
for d in dishes or []:
if d.get("is_unknown"):
sug = (
d.get("suggested_name")
or d.get("suggested_category")
or "未知"
)
keys.append(f"U:{str(sug).strip()[:24] or '未知'}")
qb = self._quantize_box(d.get("box"))
keys.append(f"U:{qb}")
else:
name = (d.get("label") or d.get("name") or "").strip()
if name: