This commit is contained in:
parent
9caf89e48b
commit
ae1f8b9830
|
|
@ -16,7 +16,7 @@ class Config:
|
|||
# 你的Plate检测模型路径(相对项目根目录);若存在 best_openvino_model 会自动优先加载
|
||||
MODEL_PATH = str(_ROOT / "best.pt")
|
||||
|
||||
CONF_THRESHOLD = 0.8
|
||||
CONF_THRESHOLD = 0.90
|
||||
IOU_THRESHOLD = 0.45
|
||||
# 显式 imgsz,便于 OpenVINO / CPU 控制耗时;可用环境变量 DISH_YOLO_IMGSZ 覆盖
|
||||
IMGSZ = int(os.environ.get("DISH_YOLO_IMGSZ", "640"))
|
||||
|
|
|
|||
|
|
@ -31,13 +31,43 @@ def format_predict_detail(detail):
|
|||
|
||||
|
||||
def format_dish_box_label(detail):
|
||||
"""将识别结果格式化为图片框上的菜品名称标签。"""
|
||||
"""将识别结果格式化为图片框标签。
|
||||
|
||||
默认只显示菜名;设环境变量 DISH_SHOW_BOX_SCORES=1 时追加「似xx 检xx」。
|
||||
"""
|
||||
if not detail or detail.get("error"):
|
||||
return "识别失败"
|
||||
|
||||
if detail.get("is_unknown"):
|
||||
suggested = detail.get("suggested_category")
|
||||
return f"未知·{suggested}" if suggested else "未知"
|
||||
return detail.get("label") or "未知"
|
||||
base = f"未知·{suggested}" if suggested else "未知"
|
||||
else:
|
||||
base = detail.get("label") or detail.get("name") or "未知"
|
||||
|
||||
try:
|
||||
from dao.settings import DISH_SHOW_BOX_SCORES
|
||||
show_scores = bool(DISH_SHOW_BOX_SCORES)
|
||||
except Exception:
|
||||
show_scores = False
|
||||
if not show_scores:
|
||||
return str(base)
|
||||
|
||||
def _fmt(v):
|
||||
try:
|
||||
return f"{float(v):.2f}" if v is not None else None
|
||||
except (TypeError, ValueError):
|
||||
return None
|
||||
|
||||
sim = _fmt(detail.get("score"))
|
||||
det = _fmt(detail.get("det_conf"))
|
||||
bits = []
|
||||
if sim is not None:
|
||||
bits.append(f"似{sim}")
|
||||
if det is not None:
|
||||
bits.append(f"检{det}")
|
||||
if not bits:
|
||||
return str(base)
|
||||
return f"{base} {' '.join(bits)}"
|
||||
|
||||
|
||||
class PendingLearningUIMixin:
|
||||
|
|
|
|||
|
|
@ -71,6 +71,9 @@ DISH_DEVICE_STATUS_ENABLED = os.environ.get('DISH_DEVICE_STATUS_ENABLED', '1') =
|
|||
DISH_SYNC_ON_START = os.environ.get('DISH_SYNC_ON_START', '1') == '1'
|
||||
DISH_SYNC_INTERVAL = int(os.environ.get('DISH_SYNC_INTERVAL', 300)) # 默认 5 分钟
|
||||
|
||||
# 识别框是否显示「似xx 检xx」(默认关;需要时 set DISH_SHOW_BOX_SCORES=1)
|
||||
DISH_SHOW_BOX_SCORES = os.environ.get('DISH_SHOW_BOX_SCORES', '0') == '1'
|
||||
|
||||
DEBUG = True
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1759,12 +1759,8 @@ class BaseDishApp(PendingLearningUIMixin):
|
|||
print(f"[live] preview failed: {e}")
|
||||
|
||||
def _live_dish_label(self, dish):
|
||||
if not dish:
|
||||
return "未知"
|
||||
if dish.get("is_unknown"):
|
||||
sug = (dish.get("suggested_category") or "").strip()
|
||||
return f"未知·{sug}" if sug else "未知"
|
||||
return (dish.get("label") or dish.get("name") or "未知").strip() or "未知"
|
||||
from ui.pending_learning_ui import format_dish_box_label
|
||||
return format_dish_box_label(dish)
|
||||
|
||||
def _draw_live_overlay_pil(self, pil_im, dishes, sx=1.0, sy=1.0):
|
||||
"""在已缩放预览图上画识别框:整图一次 alpha 合成,避免逐框卡顿。"""
|
||||
|
|
@ -1967,6 +1963,7 @@ class BaseDishApp(PendingLearningUIMixin):
|
|||
boxes,
|
||||
auto_pending=False,
|
||||
crop_images=crop_arrays,
|
||||
det_confs=[c.get("conf") for c in crop_items],
|
||||
)
|
||||
self._last_detect_fp = fp
|
||||
self._last_live_dishes = list(dishes or [])
|
||||
|
|
@ -2404,6 +2401,7 @@ class BaseDishApp(PendingLearningUIMixin):
|
|||
f"正在识别第 {cur} 张…", "busy"
|
||||
),
|
||||
crop_images=crop_arrays,
|
||||
det_confs=[c.get("conf") for c in crop_items],
|
||||
)
|
||||
preview = labeled_path or visualize_save_path
|
||||
if preview:
|
||||
|
|
@ -2523,7 +2521,9 @@ class BaseDishApp(PendingLearningUIMixin):
|
|||
return
|
||||
|
||||
final_result, _, _unknown_count, labeled_path, dishes = self.run_plate_predict_batch(
|
||||
save_path, cropped_file_paths, boxes, crop_images=crop_arrays,
|
||||
save_path, cropped_file_paths, boxes,
|
||||
crop_images=crop_arrays,
|
||||
det_confs=[c.get("conf") for c in crop_items],
|
||||
)
|
||||
preview = labeled_path or visualize_save_path
|
||||
self.report_recognition(save_path, dishes, preview)
|
||||
|
|
|
|||
|
|
@ -31,13 +31,43 @@ def format_predict_detail(detail):
|
|||
|
||||
|
||||
def format_dish_box_label(detail):
|
||||
"""将识别结果格式化为图片框上的菜品名称标签。"""
|
||||
"""将识别结果格式化为图片框标签。
|
||||
|
||||
默认只显示菜名;设环境变量 DISH_SHOW_BOX_SCORES=1 时追加「似xx 检xx」。
|
||||
"""
|
||||
if not detail or detail.get("error"):
|
||||
return "识别失败"
|
||||
|
||||
if detail.get("is_unknown"):
|
||||
suggested = detail.get("suggested_category")
|
||||
return f"未知·{suggested}" if suggested else "未知"
|
||||
return detail.get("label") or "未知"
|
||||
base = f"未知·{suggested}" if suggested else "未知"
|
||||
else:
|
||||
base = detail.get("label") or detail.get("name") or "未知"
|
||||
|
||||
try:
|
||||
from dao.settings import DISH_SHOW_BOX_SCORES
|
||||
show_scores = bool(DISH_SHOW_BOX_SCORES)
|
||||
except Exception:
|
||||
show_scores = False
|
||||
if not show_scores:
|
||||
return str(base)
|
||||
|
||||
def _fmt(v):
|
||||
try:
|
||||
return f"{float(v):.2f}" if v is not None else None
|
||||
except (TypeError, ValueError):
|
||||
return None
|
||||
|
||||
sim = _fmt(detail.get("score"))
|
||||
det = _fmt(detail.get("det_conf"))
|
||||
bits = []
|
||||
if sim is not None:
|
||||
bits.append(f"似{sim}")
|
||||
if det is not None:
|
||||
bits.append(f"检{det}")
|
||||
if not bits:
|
||||
return str(base)
|
||||
return f"{base} {' '.join(bits)}"
|
||||
|
||||
|
||||
class PendingLearningUIMixin:
|
||||
|
|
@ -689,6 +719,7 @@ class PendingLearningUIMixin:
|
|||
def run_plate_predict_batch(
|
||||
self, source_image_path, cropped_file_paths, boxes,
|
||||
progress_callback=None, auto_pending=True, crop_images=None,
|
||||
det_confs=None,
|
||||
):
|
||||
"""对多个裁剪区域识别。
|
||||
|
||||
|
|
@ -698,6 +729,7 @@ class PendingLearningUIMixin:
|
|||
|
||||
cropped_file_paths: 裁剪图路径列表(可与 crop_images 二选一/并用)
|
||||
crop_images: 可选 BGR ndarray 列表,优先用于特征提取(免读盘)
|
||||
det_confs: 可选 YOLO 检测置信度列表(与 boxes 对齐)
|
||||
|
||||
返回:
|
||||
final_result, dish_labels, unknown_count, labeled_path, dishes
|
||||
|
|
@ -728,6 +760,7 @@ class PendingLearningUIMixin:
|
|||
if progress_callback:
|
||||
progress_callback(i + 1, n)
|
||||
box = boxes[i] if boxes and i < len(boxes) else None
|
||||
det_conf = det_confs[i] if det_confs and i < len(det_confs) else None
|
||||
img_path = cropped_file_paths[i] if i < len(cropped_file_paths) else None
|
||||
try:
|
||||
detail = self.manager.predict_from_feature(
|
||||
|
|
@ -737,12 +770,15 @@ class PendingLearningUIMixin:
|
|||
)
|
||||
if detail.get("is_unknown"):
|
||||
unknown_count += 1
|
||||
dish_labels.append(format_dish_box_label(detail))
|
||||
label_src = dict(detail)
|
||||
label_src["det_conf"] = det_conf
|
||||
dish_labels.append(format_dish_box_label(label_src))
|
||||
final_result += f"【菜品{i + 1}】{format_predict_detail(detail)}\n"
|
||||
dishes.append({
|
||||
"index": i + 1,
|
||||
"label": detail.get("label"),
|
||||
"score": detail.get("score"),
|
||||
"det_conf": det_conf,
|
||||
"is_unknown": bool(detail.get("is_unknown")),
|
||||
"suggested_category": detail.get("suggested_category"),
|
||||
"pending_id": detail.get("pending_id"),
|
||||
|
|
@ -759,6 +795,7 @@ class PendingLearningUIMixin:
|
|||
"index": i + 1,
|
||||
"label": None,
|
||||
"score": None,
|
||||
"det_conf": det_conf,
|
||||
"is_unknown": True,
|
||||
"suggested_category": None,
|
||||
"pending_id": None,
|
||||
|
|
|
|||
Loading…
Reference in New Issue