import json import os import re from typing import Dict, List def _list_dirs(path: str) -> List[str]: if not os.path.isdir(path): return [] return [d for d in os.listdir(path) if os.path.isdir(os.path.join(path, d))] def _normalize(name: str) -> str: # 去括号/方括号内注释,统一去空格 name = re.sub(r"[((].*?[))]", "", name) name = re.sub(r"\[.*?\]", "", name) return name.replace(" ", "").strip() _SHAPE_COOKING_TERMS = [ "切丝", "切片", "切丁", "切段", "切块", "切条", "切末", "切花", "丝", "片", "丁", "段", "块", "条", "末", "清炒", "红烧", "爆炒", "炒", "煮", "炖", "蒸", "炸", "拌", "焯", "烤", "煎", "烩", "烫", ] def _base_ingredient(name: str) -> str: n = _normalize(name) for kw in _SHAPE_COOKING_TERMS: n = n.replace(kw, "") n = re.sub(r"[、,,·\-/]", "", n) return n.strip() def load_alias_map(fp: str | None = None) -> Dict[str, str]: if fp and os.path.isfile(fp): with open(fp, "r", encoding="utf-8") as f: return json.load(f) return {} def build_labels(mode: str, alias_map_path: str | None = None) -> List[str]: # 使 dataset 路径与运行目录无关:基于项目根目录(exp_multimodal 的上一级) base = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "dataset") if mode == "dish": root = os.path.join(base, "DishClassification", "train") elif mode == "whole": root = os.path.join(base, "WholeIngredientRecognition", "train") elif mode == "processed": root = os.path.join(base, "ProcessedIngredientRecognition", "train") else: return [] raw = _list_dirs(root) alias = load_alias_map(alias_map_path) std: List[str] = [] for r in raw: n = _normalize(r) n = alias.get(n, n) if mode in ("whole", "processed"): n = _base_ingredient(n) if n: std.append(n) # 去重并排序 return sorted(list(dict.fromkeys(std)))