2025-9-8
1 | //以“菜”为分割单元,在 annotation 中记录菜名、烹饪方式,并在 ingredients list 中写入每个食材及其切法属性。 |
标注食材:层次化标签体系
用“菜品级(dish-level)实例掩码 + 每个掩码的多标签食材列表与属性”作为主标注策略。
大类➡️食材➡️菜名(supercategory → ingredient → fine-grained synonyms / dish names)
- 食材大类:纯荤、纯素、荤素、水果、主食、其他
- 食材类别:西兰花、猪肉、圣女果、米饭、汤……
- 属性标注:切割方式、烹饪方式、酱料
对于同食材不同烹饪方式:作为 attributes(元数据)记录(cooking_method, cut_style, sauce_type)
切法、调料和烹饪状态导致外观差异:设置标注属性attributes
cut_style:["whole","sliced","diced","julienne","shredded","minced", ...]cooking_state:["raw","steamed","boiled","stir_fried","deep_fried","braised","roasted","charred", ...]sauce_presence: boolean [0/1]sauce_type: ["soy_based","sweet_sour","spicy_oil"]appearance_notes(短文本):供标注员记录特殊视觉线索(如“汁水大量覆盖盘面,使米饭上色”)
Q:对于藕丁/藕片,它们虽然是同一种食材 藕,但是它们的cut style不一致,炒藕片/炒藕丁按照中餐的定义,他们能是一道菜吗?再有比如 炒土豆块/炒土豆丝。
A:它们不应该属于一道菜,如果目标是 细粒度菜品识别 → 分成不同类别(因为 appearance 差异大,模型才能学到)。如果目标是 营养/食材级分析 → 仍归为 Lotus root、Potato,切法存储在属性 cut_style。(可考虑)分配两个id(也就是对同一道菜分配不同的id)食材级别的分析用一种id分配、菜品又分配另外一套id类别。
标注单元 = 一道菜(Dish Instance)
- 每张图片 → 标注所有菜品的分割区域(Polygon/Brush)。
- 每个区域有:
dish_name(菜品名称,例如 “红烧肉”)ingredients(食材列表,例如 Pork, SoySauce, Sugar, Oil …)cooking_style(Braised, Fried, Sweet-Sour …)cut_style(Slice, Chunk, Strip …)
对于不同的下游任务,使用的item:
- 分割任务 → 用 polygon 区分每道菜。
- 菜品分类 → 用
dish_name。 - 食材识别 → 用
ingredientslist。 - 细粒度研究(切法/烹饪风格) → 用
cut_style和cooking_style。 - VQA / 开放词汇分割 → “这道菜有辣椒吗?” → 查
ingredients。
另外一种想法:标注菜品
==或者是标注菜品,以食材作为附加属性?“菜品级语义分割”作为数据集的主任务标注,再在 JSON metadata 里附加“食材-切法-烹饪方式”等辅助信息。训练时,分割网络输出 mask,分类器输出菜品类别,额外分支输出 metadata。==
分割
现代 Transformer-based 方法(比如 Mask2Former、DETR 系列)能做到:
- 输入:整张图片,一张 RGB 图像 $I \in \mathbb{R}^{H \times W \times 3}$。
- 输出:一组 $\{mask_i, class_i\}$
- $mask_i$:第 i 道菜的像素集合
- $class_i$:第 i 道菜的类别(锅包肉 / 红烧肉 / 腊肉炒藕丁)
模型处理流程(以 Transformer 为例)
以 ViT/Mask2Former 为参考,把你的输入输出串起来:
(1) 输入图像
一张菜品混合的餐盘图像。
(2) 特征提取(Backbone)
- 用 ViT(Vision Transformer)或 Swin Transformer 提取 patch 特征。
- 图像 $H \times W$ → patch embedding → Transformer encoder → 全局上下文特征。
(3) 分割头(Segmentation head / Mask Transformer)
两种典型做法:
- ViT-DeepLab 风格:
- 特征 → 上采样 → 每个像素预测属于哪个菜品类别。
- 输出 = 语义分割 mask。
- Mask2Former 风格:
- 特征 → query-based decoder → 每个 query 预测一个 mask。
- 输出 = 一组 {mask, class} 对象。
- class 就是“锅包肉/红烧肉”等类别。
(4) 附加任务(metadata 预测,可选)
有了 mask + class 后,你还可以接:
- 多标签分类器:对每个 mask 区域,预测 ingredients list、cut style、cooking method。
- 输入:mask 区域的 pooled feature
- 输出:多标签结果(如腊肉-sliced, 藕-diced, 炒-fry)
- 这样,数据的 metadata 就能发挥作用。
可能的输出格式:
1 | [ |