设想你是一位舞台剧导演,第一次走进一间还没布置的空房间。为了排出好戏,你必须做三件事:先环顾四周,认出每一样道具——床、书桌、台灯、椅子;接着判断它们之间怎么摆放——台灯在书桌上,椅子挨着书桌,书桌在床的左边;最后把这些信息画成一张“走位图”,让所有人都能一眼看懂这个舞台。人工智能做“室内场景图生成”,扮演的正是这位导演:物体是演员,空间关系是走位,最终输出一张结构化的“关系剧本”——场景图。这张图不是一张普通照片,而是让机器真正“看懂”房间的语义地图。机器人靠它导航找物、抓取操作,人机交互靠它理解你的指令。本文将从“清点道具”讲到“编排走位”,带你零基础看懂场景图生成的全过程。
一句话价值:场景图是 3D 场景理解从“看见”走向“看懂”的桥梁,掌握它能帮你在机器人、具身智能、空间智能等方向建立起结构化推理的核心竞争力。
可视化演示
通过场景图结构、联合学习管线和机器人导航应用三个维度,动态展示物体检测与空间关系推理的图神经网络方法及其在3D场景理解中的应用。
本节配有交互动效(进入视口后自动加载,约 3KB)。
室内场景图结构 物体节点+空间关系边 结构化语义表征 Node+Edge=SceneGraph
场景图基础概念
一位导演走进空房间,第一件事不是举起手机拍照,而是拿出纸笔:床在西北角,书桌靠着东墙,台灯摆在书桌上,椅子卡在书桌右侧。他画的不是照片,而是一张“走位图”——谁在哪、谁挨着谁、谁托着谁,全用线条和标签串起来。这张走位图,就是舞台的“关系剧本”。
在 AI 眼里,“走位图”被称为场景图(Scene Graph)。它用一张图概括室内场景:节点是物体实例,边是物体之间的空间或语义关系。普通图像只是一堆像素,机器看到的是颜色和纹理;场景图则把这些像素“翻译”成结构化符号,让机器能像导演一样问出“台灯在什么上面”。
场景图通常写作带标签的有向图。节点可以携带属性,比如类别、位置、尺寸;边则有类型,比如“在……上”“在……旁边”“在……左侧”。一条边配上两端的节点,就构成一个三元组,例如(台灯,在……上,书桌)。识别物体回答“有什么”,加上关系才说清“怎么摆”,这正是场景图相对普通检测的增量价值。
导演的走位图决定整出戏怎么调度,场景图则决定机器怎么理解环境:导航要找“床”、抓取要懂“支撑”,答案都写在这张关系剧本里。有了它,机器才从“看见”走向“看懂”。
- 节点集合 VV 是场景中所有物体的集合,每个物体是一个节点 o_i,相当于导演手里的演员名单。
- 边集合 EE 记录物体之间存在的关系,每条边连接两个节点,相当于走位图上的一条连线。
- 三元组语义e_ij 写成 (o_i, r_ij, o_j),表示“物体 o_i 与物体 o_j 之间具有关系 r_ij”。
对象检测定位
导演清点道具,得先认出每一样东西:那团灰影是床,那四条腿是椅子。AI 的第一步也一样,叫物体检测——找到每个物体画个框,并标出类别。这些检测结果就是场景图的“候选演员”。
在 2D 图片里,检测框是矩形;在 3D 点云里,则是带真实尺度的 3D 包围盒。常见做法是先让卷积网络或点云网络提取特征,再回归出包围盒坐标与类别得分。特征提取得好不好,直接决定后续关系推理的上限。
检测质量如何衡量?最常用的是 IoU(交并比),即预测框与真实框重叠区域占合并区域的比例。IoU 越高,说明框打得越准;超过 0.5 通常算成功命中。这个数字就像导演检查道具摆位是否“严丝合缝”。
道具清点得越准,后面的走位编排才越可信。如果检测把椅子漏掉或框歪了,关系推理就像导演面对一张模糊的演员名单,自然会频频出错。检测是整条流水线的地基。
- 求交集面积先计算预测框与真实框重叠部分的面积,3D 情况下则是重叠体积。
- 求并集面积再计算两个框覆盖的总面积,等于两者面积之和减去重叠面积。
- 计算比值交集越大、并集越小,比值越接近 1,说明定位越精确。
关系推理模型
导演判断“台灯在书桌上”,不会只看台灯本身——他要看台灯与书桌的相对高差、接触面,以及周围有没有别的物体干扰视线。AI 的关系推理也从来不是“只看一个物体”,而是成对地、结合上下文地看。
关系推理的核心任务:给定两个已检测出的物体 o_i 和 o_j,预测它们之间最可能的关系类别 r_ij。难点在于关系高度依赖语境:同一个“在……上”,发生在杯子与桌子之间,和发生在鸟与树之间,视觉特征完全不同。关系类别体系通常包含“支撑”“旁边”“左”“右”“前方”“后方”等空间谓词。
主流做法是把两个物体的视觉特征 f_i、f_j 与两者的联合空间特征 f_ij 拼接成一个向量,经过全连接层映射,再用 softmax 输出各类关系的概率。更进一步的模型会引入注意力机制或图神经网络,让周围物体“投票”参与当前关系的判断——这就像导演参考整个舞台布景再下结论。
就像导演结合整台布景判断道具走位,关系推理模型也在“群体语境”中做判断。孤立地看两个框永远不够,把邻居信息卷进来,关系才真正“看得懂”。
- 特征拼接把物体 i 的特征、物体 j 的特征,以及两者的空间关系特征(相对位置、重叠度等)拼接成一个长向量,表示“这对物体”的整体特征。
- 线性映射用权重矩阵 W 把拼接向量映射到“关系类别得分”空间,相当于对每个候选关系打一个原始分。
- softmax 归一化把原始分数转成一组和为 1 的概率,得分最高的类别就是模型认为的关系。
3D场景图构建
平面走位图贴在纸上,立体舞台却需要纵深:台灯是否真的压在书桌上,椅子是贴着桌子还是隔了半米?从 2D 走向 3D,场景图才获得真实物理约束,机器人也才能靠它规划抓取。
3D 场景图构建的典型流水线:先用 3D 检测与分割从点云中切出物体及包围盒;接着对每个物体对编码空间关系(支撑、邻近、朝向等);然后让图神经网络在节点之间传递消息,使每个节点的特征吸收邻居信息;最后联合输出物体标签与边关系。
图神经网络(GNN)是构建阶段的核心。每一层,节点把自己的特征发给邻居,同时收拢邻居发来的特征,经加权求和与非线性变换后更新自己。如此迭代几层,每个节点都携带了“局部社会关系”的信息,关系预测自然更准。整个流水线常用多任务损失联合训练:检测损失加上关系损失,让两个目标互相促进。
3D 场景图等于把导演的走位图从平面升级为带真实尺度的立体模型。有了深度、支撑和遮挡信息,机器不再只是“看着像”,而是“物理上站得住”,这正是机器人进入真实房间的前提。
- 邻域集合N(i)∪{i} 表示物体 i 的所有邻居节点加上它自己,相当于走位图上与 i 直接相连的角色。
- 聚合求和把所有邻居的特征向量逐元素相加,完成一次“意见汇总”,把局部布景的集体信息收进来。
- 线性变换与激活用权重 W^(l) 对汇总结果做线性变换,再经过非线性激活函数 σ(如 ReLU),得到第 l+1 层的新特征。
数据与评测
一出戏好不好,要由评审团打分。场景图模型做得好不好,也要有标准答案。3DSSG(3D Scene Graph)数据集是目前室内 3D 场景图最常用的基准之一,它来自 ScanNet 扫描的数百个真实室内场景,标注了物体的 3D 包围盒和物体间的成对关系。
打开数据统计会发现一个显著特点:关系类别呈长尾分布。“在……旁边”“在……上”这类常见关系样本极多,而“支撑着”“属于”等关系样本稀少。模型很容易只顾头部关系、忽略尾部关系,这也是“关系类别越细越难学”的深层原因。
评测指标上,场景图领域常用 Recall@K:把所有预测关系按置信度排序,取前 K 个,看真实关系命中了多少。K 越大,考核越宽松;还可以在此基础上加“按类别平均”的变体,惩罚只命中高频类别的取巧模型。
评审标准决定了导演努力的方向。长尾分布提醒我们:真正的场景图高手,不是只会说“旁边”和“上面”,而是连冷门关系也能在关键时刻拿到分。
- 预测排序模型对所有候选三元组按置信度从高到低排序,就像导演把最认可的走位先列出来。
- 截取前 K 个只保留前 K 条预测,构成集合 E_hat_K,K 是评审团允许的“答题额度”。
- 平均命中率逐一检查真实关系 e 是否落在前 K 条里,命中记 1,最后对所有真实关系取平均,得到 0 到 1 之间的得分。
应用与挑战
彩排做得再好,也要登上真实舞台。场景图从论文走向产品,最活跃的舞台是机器人。服务机器人靠场景图构建语义地图:它知道哪里有“床”、哪里有“门”,导航时不再盲目避障,而是带着语义找路。
抓取规划则受益于关系中的“支撑链”:要拿起书桌上的杯子,先要知道杯子被什么支撑,会不会带倒旁边的台灯。人机交互同样需要场景图:你说“帮我把沙发旁的灯打开”,机器得先把自然语言里的关系词解析到场景图节点上,才能锁定时体。
然而公演总有意外。开放世界的类别远超训练数据,长尾关系依旧难学,动态场景中物体随时在移动,真实传感器噪声也会让检测与关系双双退化。如何用自监督、大模型与在线学习补齐这些短板,是通往“空间智能”这一更大蓝图的关键挑战。
导演终其一生都在应对舞台上的意外,机器也一样。场景图给了它一份结构化剧本,让它在复杂真实世界里可以推理、可以预演、可以从容应对,这正是空间智能与通用 AI 探索中最踏实的台阶。
- 统计成功次数在 N 次真实任务(如“把杯子放到书桌上”)中,记录机器人完全成功的次数。
- 计算比例用成功次数除以总尝试次数,得到 0 到 1 之间的成功率,作为端到端能力的考核。
AI 应用场景
服务机器人语义导航
阶段:感知与语义建图
解决的问题:传统导航把环境当成“障碍物集合”,只回答“哪里有路”,回答不了“床在哪里”。场景图生成把原始点云升级成带关系的语义地图,让机器人能把用户指令映射到具体物体节点,实现“找物式”导航。
具体案例:某酒店送物机器人入住前先扫描客房,实时构建场景图。客人说“把水放到床头柜上”,机器人先在场景图中检索“床头柜”节点,再规划路径并完成放置,全程避开床、椅子等障碍物。
机械臂抓取与操作
阶段:决策与规划
解决的问题:抓取不只是“伸手去拿”,还要判断物体间的支撑与遮挡关系。场景图中的支撑链让机械臂提前预判“抽走桌布会不会带倒杯子”“先拿上面的玩偶还是先拿下面的书”。
具体案例:家务机器人面对堆叠的餐盘,先读取场景图确认每个盘子的支撑关系,按“自上而下”顺序抓取,避免强行抽拉导致整体倒塌;抓取失败时还会更新场景图状态,重新规划。
人机交互与视觉助手
阶段:多模态理解与任务执行
解决的问题:自然语言指令充满关系词:“左边的”“上面的”“旁边的”。传统视觉问答只能“看图说话”,无法精确指代对象。场景图提供可查询的关系索引,让“指代消解”从猜测变成查表。
具体案例:视障辅助眼镜实时构建室内场景图,用户询问“我右手边的椅子在哪”,系统在图中找到与“用户右侧”匹配的椅子节点,生成语音引导并提示距离与方向。
Python 演示
"""从3D包围盒构建室内场景图, 并用规则基线评测关系预测效果"""import itertools # 物体名 -> 3D包围盒 (xmin, ymin, zmin, xmax, ymax, zmax), y 轴竖直向上OBJS = { "table": (0.0, 0.0, 0.0, 2.0, 1.0, 1.0), "chair": (2.2, 0.0, 0.1, 2.8, 0.9, 0.8), "lamp": (0.7, 1.0, 0.3, 1.0, 1.9, 0.6), "book": (0.4, 1.0, 0.2, 0.9, 1.05, 0.5), "sofa": (-0.3, 0.0, -2.2, 1.5, 0.8, -0.2),} # 真实关系三元组: (主语, 谓语, 宾语), 表示 主语 谓语 宾语GT = [ ("lamp", "on", "table"), ("book", "on", "table"), ("chair", "right", "table"), ("sofa", "behind", "table"),] def center(box): return ((box[0] + box[3]) / 2.0, box[1], (box[2] + box[5]) / 2.0) def overlap_xz(a, b): ox = min(a[3], b[3]) - max(a[0], b[0]) oz = min(a[5], b[5]) - max(a[2], b[2]) return max(0.0, ox) * max(0.0, oz) def base_area(box): return (box[3] - box[0]) * (box[5] - box[2]) def predict_relation(a, b): """预测 a 相对 b 的关系: on / right / left / behind""" if abs(a[1] - b[4]) < 0.1 and overlap_xz(a, b) > 0.5 * base_area(a): return "on" ax, az = center(a)[0], center(a)[2] bx, bz = center(b)[0], center(b)[2] if abs(ax - bx) > abs(az - bz): return "right" if ax > bx else "left" return "behind" if az < bz else "nothing" def build_graph(threshold=1.8): """只对水平距离较近的物体对预测关系, 输出场景图三元组""" edges = [] for a, b in itertools.permutations(OBJS, 2): ax, az = center(OBJS[a])[0], center(OBJS[a])[2] bx, bz = center(OBJS[b])[0], center(OBJS[b])[2] if (ax - bx) ** 2 + (az - bz) ** 2 > threshold ** 2: continue rel = predict_relation(OBJS[a], OBJS[b]) if rel != "nothing": edges.append((a, rel, b)) return edges def evaluate(edges): gt_set = set(GT) hits = sum(1 for e in edges if e in gt_set) recall = hits / float(len(gt_set)) precision = hits / float(len(edges)) print("预测三元组数: %d" % len(edges)) print("命中真实关系: %d / %d" % (hits, len(gt_set))) print("召回率: %.2f, 精度: %.2f" % (recall, precision)) def main(): edges = build_graph() print("==== 室内场景图(规则基线) ====") for sub, rel, obj in sorted(edges): print("%s -[%s]-> %s" % (sub, rel, obj)) print("==== 与人工标注对比 ====") evaluate(edges) if __name__ == "__main__": main()
OBJS = {...}定义 5 个室内物体的 3D 包围盒,相当于导演的“道具清单”。GT = [...]人工标注的真实关系三元组,是评审团的“标准答案”。def predict_relation(a, b)用几何启发式判断 a 相对 b 的关系:先查“支撑”,再看水平与纵深方向。if abs(a[1] - b[4]) < 0.1 and overlap_xz(...)物体底面贴近另一物体顶面且水平重叠足够大,判定为“在……上”。def build_graph(threshold=1.8)只对水平距离较近的物体对预测关系,模拟真实场景图的稀疏连边。for a, b in itertools.permutations(OBJS, 2)遍历所有有序物体对,因为“椅子在桌子左边”与“桌子在椅子右边”是两条不同关系。if rel != "nothing": edges.append((a, rel, b))只有预测出有效关系才连边,像导演只在有走位的地方画线。def evaluate(edges)用“命中数 / 真实数”算召回率,用“命中数 / 预测数”算精度。hits = sum(1 for e in edges if e in gt_set)统计预测三元组中命中标准答案的条数。if __name__ == "__main__": main()程序入口,直接运行即可看到场景图与评测结果。
常见误区
误区物体检测已经能告诉我房间里有什么,再在框和框之间画几根线,不就是场景图了吗?感觉只是把检测结果换了个名字。
正解检测与场景图的最大差别在“关系”二字。场景图的每条边都是一个需要学习的语义或空间判断——“支撑”“属于”“在……左边”无法靠画线完成。好比导演清点完道具,若不编排走位,演员名单永远不是剧本。丢到下游任务里,没有关系的图几乎帮不上机器人抓取或导航。
为何常见:因为检测输出的框加类别与场景图的节点长得几乎一样,视觉上的相似掩盖了“关系推理”这一层本质新增。
误区台灯在书桌上,用 y 坐标一比就能判断;关系推理没必要上模型,写几条 if-else 就够了。
正解简单几何规则在“接触支撑”这类情况下有效,但面对“旁边”“前方”“里面”等语义关系,几何阈值在不同场景、不同尺度下千差万别;同类关系还常有视觉歧义。学习型模型能从海量数据中学到规则无法穷举的判别模式,正如导演对走位的判断来自经验而非一把尺子。
为何常见:因为少量启发式规则在简单样例上表现不错,让人误以为数据里全是这种“可手写”的规律。
误区给 2D 检测结果配上深度图,再照搬原来的关系推理,输出的不就是 3D 场景图了吗?
正解3D 场景图要求真实的 3D 包围盒、相机位姿与几何一致性,节点和边的语义都建立在三维物理之上;支撑、遮挡、空间包含等关系在 2D 中本就模糊。简单“贴深度”无法处理被遮挡物体和尺度漂移,必须重新设计检测、分割与关系编码的整个管线。
为何常见:因为加了深度的可视化“看起来”已经很立体,容易让人低估几何一致性带来的实际难度。
误区关系种类定义得细一点,模型显得更聪明,比如把“旁边”拆成“左侧”“右侧”“前方”“后方”,这肯定能提升能力。
正解关系类别越细分,样本越稀疏,长尾越严重,模型越难学,评测也越不稳定。真实系统往往在“判别粒度”与“数据支撑”之间取舍——正如剧本不能给每个龙套都写独白,否则主角反而没戏。合理做法是保留高频粗粒度关系,对稀有细粒度关系做层级化处理。
为何常见:直觉上“更细等于更智能”,忽略了监督学习对样本分布的硬性依赖。
面试题
Q1. 场景图中“节点”表示什么?
- A.场景中的物体实例← 正确答案
- B.图像的单个像素
- C.相机的内外参数
- D.数据库的索引字段
答案:A。场景图的节点就是“演员名单”上的物体实例,每个检测框对应一个节点;像素、相机参数和数据库字段都不是场景语义的载体。
Q2. 场景图中“边”的主要作用是什么?
- A.描述物体间的空间或语义关系← 正确答案
- B.标出图像边缘的像素位置
- C.记录场景的光照方向和强度
- D.保存物体的三维网格顶点
答案:A。边是走位图上的连线,记录“谁和谁是什么关系”;图像边缘、光照和网格顶点都与场景图结构无关。
Q3. 下列哪项最适合衡量检测框与真实框的重合程度?
- A.交并比 IoU← 正确答案
- B.交叉熵损失
- C.均方误差 MSE
- D.KL 散度距离
答案:A。IoU 等于交集除以并集,直观反映两个框贴得多紧,是检测任务的标准度量;交叉熵、MSE 和 KL 散度多用于分类或分布拟合,不直接衡量框的重叠。
Q4. 关系推理中“上下文建模”的核心思想是什么?
- A.借助其他物体信息辅助判断← 正确答案
- B.只利用单个物体的外观特征
- C.对每个物体独立做出判断
- D.放弃空间位置只用颜色信息
答案:A。像导演结合整台布景看走位一样,关系推理需要用邻居物体的特征与空间线索来消解歧义;只看单个物体或丢弃空间信息,会让“在……上”和“在……旁”难以区分。
Q5. 3D 场景图相比 2D 场景图的优势包括哪些?
- A.提供真实尺度支持抓取规划← 正确答案
- B.更容易判断支撑与遮挡关系← 正确答案
- C.完全不需要物体检测操作
- D.无需考虑相机位姿对齐
答案:AB。3D 包围盒自带真实尺度,支撑、遮挡也有物理依据,对抓取和导航更友好;但构建 3D 场景图仍然依赖检测分割,并且必须做相机位姿对齐,C 和 D 都不符合实际。
Q6. 图神经网络消息传递中,节点特征更新的一般形式是什么?
- A.聚合邻居特征并经非线性变换← 正确答案
- B.对每个节点独立做池化操作
- C.仅更新边权不更新节点特征
- D.用全连接层直接分类整张图
答案:A。GNN 每一层都让节点“听取周围朋友的意见”——先聚合邻居特征,再做线性变换与激活;B 是独立池化、C 只改边、D 是整图分类,都不符合逐层消息传递的定义。
Q7. 室内场景图生成面临的主要挑战有哪些?
- A.关系类别呈长尾分布← 正确答案
- B.同类关系存在视觉歧义← 正确答案
- C.数据集中所有关系等频出现
- D.物体检测结果完全准确无误
答案:AB。真实数据里“旁边”“上面”占大头、稀有关系样本少,且同样一句“在……上”在不同物体组合下视觉差异巨大;C 与事实相反,D 是理想假设而非现实挑战。
Q8. Recall@K 指标衡量的是什么?
- A.前 K 个预测对真实关系的召回率← 正确答案
- B.模型参数量的大小和内存开销
- C.数据集中物体的总数和多样性
- D.场景图像素分辨率的水平高低
答案:A。Recall@K 相当于评审团只允许导演展示 K 条走位,看真实关系被覆盖的比例;它考核的是“预测质量与排序能力”,与参数规模、数据量、像素无关。
Q9. 3DSSG 数据集主要提供什么?
- A.室内场景的 3D 扫描与关系标注← 正确答案
- B.互联网爬取的图片分类标签
- C.纯文本的物体描述文档资料
- D.音频场景的波形标注数据
答案:A。3DSSG 来自真实室内扫描,包含物体 3D 包围盒与成对关系标注,是训练和评测 3D 场景图的基准;它不涉及图像分类、文本或音频。
Q10. 场景图在机器人领域的典型应用有哪些?
- A.导航时理解环境语义结构← 正确答案
- B.抓取前推断物体支撑关系← 正确答案
- C.识别物体后直接忽略关系
- D.用关系图谱进行人机对话← 正确答案
答案:ABD。场景图让导航“带着语义找路”,让抓取“按支撑链顺序操作”,让人机交互“把语言关系解析到节点”;识别后忽略关系等于把导演辛苦排的走位扔掉,显然不是应用方式。