Think, Act, Build: An Agentic Framework with Vision Language Models for Zero-Shot 3D Visual Grounding
Paper: arXiv:2604.00528 Code: WHB139426/TAB-Agent Code reference:
main@a8122594(2026-04-05)
1. Motivation (研究动机)
3D Visual Grounding (3D-VG) 的目标是根据自由形式语言描述,在 3D 场景里定位目标物体并输出 3D bounding box。它直接服务于 human-robot interaction、embodied navigation、AR/VR 等任务:机器人或智能体如果只能理解“红色椅子”这种类别词,而不能理解“靠近桌子的左侧枕头”这类带关系与视角条件的描述,就很难在真实室内环境中执行可交互任务。
现有路线有两个关键瓶颈。第一,fully-supervised 3D-VG 依赖高质量、密集标注的 3D vision-language 数据,标注成本高,而且对 open-world / open-vocabulary 场景泛化有限。第二,许多 zero-shot 方法虽然利用 LLM/VLM,但仍把预处理点云和 3D proposals 当作强先验:先生成候选 3D boxes,再让模型做 proposal matching。这会把 3D grounding 降级为“在已有地图里挑一个框”,在没有预扫描点云或 proposal 质量不足时失效。
更接近真实感知的 2D/RGB-D 路线也有问题。VLM-Grounder 等方法尝试直接利用 2D observations,但主要靠 heuristic semantic matching 关联多视角图像;当相机视角变化大、局部 close-up 缺少上下文、或目标发生遮挡时,纯语义 tracking 容易断裂,最终得到碎片化 3D geometry。TAB 要解决的具体问题就是:不依赖预处理 3D point cloud proposals,只从 raw RGB-D streams、camera intrinsics/extrinsics 与语言 query 出发,在 zero-shot setting 中把 2D semantic grounding 变成稳定的 3D object reconstruction。
Figure 1 解读:上半部分展示旧范式:输入预处理点云和 object table,VLM/LLM 主要在候选对象之间做匹配;下半部分展示 TAB:输入 RGB-D video 后,agent 在 Think-Act-Build 循环中调用 2D tools,逐步把 query 指向的物体从 2D masks lift 到 3D point cloud。关键区别不是“是否使用 VLM”,而是 grounding 的对象从静态 proposals 变成动态构建出来的 3D 几何。
2. Idea (核心思想)
核心洞察是把 3D-VG 拆成两类能力:复杂空间语义由 2D VLM agent 处理,精确 3D 结构由确定性的 multi-view geometry 处理。VLM 不需要直接“想象”3D box;它只需要在合适视角里识别、筛选、分割目标,之后由深度图、相机内外参和几何投影完成 2D-to-3D reconstruction。
TAB 的关键创新是 Semantic-Anchored Geometric Expansion:先用 VLM+SAM 在局部视频片段中建立一个可靠的语义锚点和初始点云,提取稳定的 3D centroid;再把这个 centroid 投影回全视频的其他帧,用 FoV/depth/Z-buffer 检查绕过 VLM 纯语义 tracking 的盲区,自动收集更多视角的 masks。
与 SeeGround / SPAZER / SeqVLM 这类依赖 preprocessed 3D point cloud 或 proposals 的方法相比,TAB 的根本差异在于它先从 raw RGB-D streams “build” target geometry,再计算 box;与 VLM-Grounder 这类 2D semantic matching 方法相比,TAB 不把跨视角关联完全交给语义相似度,而是把已确认目标抽象为 3D physical anchor,并用投影几何扩展覆盖范围。
3. Method (方法)
3.1 Overall framework:Think-Act-Build agent loop
给定语言 query 、RGB-D video 、camera intrinsics 与 extrinsics ,TAB 输出目标 3D bounding box 。框架由一个 Markdown 形式的 3D-VG Skill 约束:agent 每轮先 Think,判断当前 pipeline stage 与上一步 observation;再 Act,调用 query parsing、filtering、segmentation、reconstruction、centroid completion、bbox calculation 等工具;Build 并不是最后才发生,而是在 loop 中穿插,用当前 masks 不断生成几何中间结果。
Figure 2 解读:图中以 pillow query 为例,把 TAB 分成 reference localization、semantic temporal expansion、multi-view geometric expansion 与 final 3D reconstruction。左侧的 agent 不是自由聊天模型,而是被 3D-VG Skill 约束的 ReAct executor;中间 tools 负责把 query 解析成 target class / attributes / spatial conditions,并通过 VLM 与 segmentation 选择 reference view;右侧 Build 流程先产生 和 ,再把 centroid 投影到更多帧,最后聚合 dense point cloud 并计算 box。
直觉上,TAB 有效的原因是它把“语义是否是目标”与“目标在这个视角是否可见”分开:前者由 VLM 在少量高置信视角中解决,后者由 3D centroid projection 和 depth occlusion check 解决。这样既保留 VLM 对复杂关系描述的理解能力,又避免让 VLM 在每个局部 close-up 帧里重新理解全局 spatial relation。
3.2 Reference Target Localization:从 query 到唯一 reference instance
TAB 首先调用 Query Analysis,把自然语言 query 解析成结构化 JSON,包括 target_class、visual attributes、spatial conditions、global scene_feature。例如“the pillow on the left bed … closer to the table between the beds”会被拆成目标类别 pillow、属性 top pillow、条件 left bed / closer to table、场景特征 two beds with a table between them。
之后是 coarse-to-fine filtering。论文描述中 coarse filter 使用 foundation detectors 先保留包含 target class 的帧,fine filter 再让 VLM 判断 frame 是否满足 global scene constraints。released code 中对应实现更具体:agent/tools/grounding.py 的 MasksFilterTool 直接用 SAM3 text prompt 对 target_class 生成 masks 并筛掉无 mask 的帧;VlmFilterTool 用 scene_feature prompt 让 Qwen3-VL 判断 yes/no;VlmScoreTool 再对 attributes 与 spatial conditions 打分排序。
最后,ArgmaxImageAndSegIdTool 选择最高分候选帧,调用 get_image_with_segment_and_marker() 给同类 objects 画 bbox 与数字 ID,再让 VLM 通过 vlm_identify_id() 输出目标 ID。SegmentTargetInReferenceTool 只保留该 ID 对应 mask,得到 reference tuple 。这一阶段解决的是 intra-class ambiguity:同一房间中可能有多个 pillow/chair/table,必须先把语言条件绑定到一个可视 instance。
3.3 Semantic Temporal Expansion:用局部视频连续性建立初始 3D anchor
单帧 reference mask 直接 lift 到 3D 时会受深度噪声、自遮挡和局部可见面的影响,因此 TAB 先沿时间轴做局部 tracking。给定 reference index ,agent 分别向前后两个方向扩展;每个候选帧 都由 VLM 对照 reference video context 判断目标是否仍存在。如果 VLM 验证通过,就用 segmentation 得到 ,把 加入 ;如果失败,当前方向立即停止。
论文中的 Semantic Temporal Expansion 可写为:
这一步的目的不是覆盖所有视角,而是获得一段短期、连续、语义上可靠的视频片段,用来构造初始点云 。released code 中 VlmFrameExpansionTool.run() 默认 max_filtered_num=16,沿 delta in [1,-1] 调整帧号,失败时 break;ExpandFromSecondaryViewTool 还会从高分但距离当前 frames 最远的候选中找 secondary view,补充新的局部轨迹。
3.4 Centroid Extraction:masked pixels 的 2D-to-3D lift
对 中每一帧,只把 target mask 内的 foreground pixels 逆投影到相机坐标系。论文公式为:
再用 frame-specific extrinsic 将点变换到 world coordinates:
聚合所有 valid world points 后得到 ,并计算目标的几何中心:
released code 的 generate_point_cloud() 与 depth_to_points() 对应这一过程:从 ScanNet info 读取 、color/depth resolution、axisAlignment 和 colorToDepthExtrinsics;将 depth mm 转 m;投影到 color plane 后用 mask 过滤;最后进行 axis alignment、target point sampling、SOR 与 DBSCAN largest-cluster filtering。
3.5 Multi-View Geometric Expansion:把 3D centroid 投回未观察帧
有了 后,agent 不再要求每一帧都满足完整语言描述。对任意 frame ,先把 centroid 用 inverse extrinsic 投到该相机坐标系,再用 intrinsics 得到理论像素位置和预测深度:
随后进行 visibility check:
其中 ,,论文设置 以容纳 sensor noise 和物体厚度。通过检查的 frame 会把 作为 point prompt/几何约束去找 target mask,形成 。released code 中 CentroidCompleteTool 读取 depth_tolerance = 0.4,对每个 frame 计算 u_proj/v_proj 和 depth-pixel u_depth/v_depth;若实际深度明显小于预测深度减 tolerance,则视为被遮挡并跳过;随后用 SAM3 生成 candidate masks,优先选包含投影点的 mask,若没有包含点则选距离投影点最近的 fallback mask。
3.6 Final 2D-to-3D Reconstruction and bbox
最终,TAB 对 中所有 masked pixels 再做一次 2D-to-3D inverse projection,聚合更完整的 object point cloud。为了缓解 depth sensor noise 与 segmentation artifacts,论文使用 Statistical Outlier Removal 和 DBSCAN clustering 保留主 cluster。最后根据点云 min/max extremes 计算 axis-aligned bbox:
released code 的 CalculateBboxTool 正是对 pcd.points 求 min_bound、max_bound、center 与 size,然后拼接成六维结果。
3.7 论文公式与 released code 实现差异
论文和代码整体一致,但有几个可复现性差异需要记录:
- 论文 §5.1 写 coarse detection 使用 Grounding DINO,released repo 中没有 GroundingDINO 调用;
MasksFilterTool实际用 SAM3 text prompt 做 target-class mask filtering,README 也只要求 Qwen3-VL-32B-Instruct 与 SAM3 权重。 - 论文称 Semantic Temporal Expansion 和 Multi-View Geometric Expansion 都 capped at maximum frames;
agent/tools/grounding.py中VlmFrameExpansionTool.run()默认max_filtered_num=16,eval.py/main.py的 agentmax_steps=20。如果作者实验脚本另有 override,repo 当前公开代码未体现。 - Appendix Table 4 的工具名包含
object_filter(),released registry 实际注册名是masks_filter;两者功能对应“按 target class 粗筛候选帧”,但命名与实现细节不完全一致。 - 论文表格括号中的 3D-assisted 结果使用 Mask3D proposals 做 proposal matching;released
eval.py在 native predicted bbox 后调用proposal_matching(),匹配阈值match_threshold=0.25。
3.8 Source-code-grounded pseudocode
Code reference:
main@a8122594(2026-04-05) — pseudocode and mapping based on this commit
def run_tab_agent(query, scene_id, cfg):
agent = AgentLoop(
client_id=cfg.client_id, # Qwen3-VL-32B-Instruct path
sam_path=cfg.sam_path, # SAM3 path
cache_dir=cfg.cache_dir,
scannet_video_path=cfg.video_path,
scannet_info_path=cfg.info_path,
max_steps=20,
)
agent.to(cfg.device)
agent._make_cache_dir()
copy_and_clean(f"{cfg.video_path}/{scene_id}", cfg.cache_dir)
for step in range(agent.max_steps):
thought_and_action = agent.client.response(agent.memory.with_system_prompt())
tool, args = agent._parse_action(thought_and_action)
observation = tool.run(**args)
agent.memory.add_user_message(f"Observation: {observation}")
if is_finish(thought_and_action):
return parse_bbox_from_observation(observation)
return Nonedef localize_reference_frame(image_files, query, parsed_query, sam3, vlm):
coarse = []
for image in image_files:
masks, _ = segment_mask(sam3.processor, sam3.model, image, parsed_query["target_class"])
if masks is not None:
coarse.append(image)
fine = []
for image in coarse:
if vlm_yes_no(vlm, image, parsed_query["scene_feature"]):
fine.append(image)
if len(fine) == 0: # skill fallback: do not abort immediately
fine = coarse
scores = [vlm_score(vlm, image, query, parsed_query) for image in fine]
for image in rank_by_score(fine, scores):
masks, boxes = segment_all_instances(sam3, image, parsed_query["target_class"])
marked = draw_numeric_ids(image, masks, boxes)
target_id = vlm_identify_id(marked, vlm, query, parsed_query)
if target_id >= 0:
return image, masks[target_id]
return None, Nonedef semantic_temporal_expansion(reference_image, reference_mask, query, parsed_query, max_frames=16):
clip_images = [reference_image]
clip_masks = [reference_mask]
for delta in [+1, -1]:
current = reference_image
while len(clip_images) < max_frames:
candidate = adjacent_frame(current, delta, min_idx=0, max_idx=299)
if candidate is None:
break
ok = vlm_verify_identity(reference_video=clip_images, candidate=candidate, query=query)
if not ok:
break
masks, boxes = segment_all_instances(candidate, parsed_query["target_class"])
target_id = vlm_identify_id(draw_numeric_ids(candidate, masks, boxes), query, parsed_query)
if target_id < 0:
break
if delta == +1:
clip_images.append(candidate); clip_masks.append(masks[target_id])
else:
clip_images.insert(0, candidate); clip_masks.insert(0, masks[target_id])
current = candidate
return clip_images, clip_masksdef centroid_complete(mask_filtered_images, init_pcd, scene_info, parsed_query, threshold=0.5):
centroid_world = init_pcd.get_center()
retrieved = []
for rgb_path in mask_filtered_images:
T_d2w = load_extrinsics(frame_extrinsic_path(rgb_path))
P_depth = inverse(T_d2w) @ inverse(scene_info.axis_alignment) @ homogeneous(centroid_world)
P_color = scene_info.T_d2c @ P_depth
u = round(P_color.x * scene_info.fx_color / P_color.z + scene_info.cx_color)
v = round(P_color.y * scene_info.fy_color / P_color.z + scene_info.cy_color)
if not inside_image(u, v, scene_info.color_size):
continue
actual_z = read_depth(rgb_path)[project_to_depth_pixel(P_depth)] / 1000.0
if actual_z > 0 and actual_z < P_color.z - 0.4:
continue
retrieved.append((rgb_path, (u, v)))
final_images, final_masks = [], []
for rgb_path, (u, v) in retrieved:
masks, _ = segment_mask(parsed_query["target_class"], rgb_path, threshold=threshold)
target_mask = mask_containing_point_or_nearest(masks, u, v)
if target_mask is not None:
final_images.append(rgb_path)
final_masks.append(target_mask)
return final_images, final_masksdef reconstruct_and_bbox(images, masks, scene_info):
all_points, all_colors = [], []
for image, mask in zip(images, masks):
depth = read_depth(image.replace(".jpg", ".png")) / 1000.0
points_camera = depth_to_points(depth, scene_info.fx_depth, scene_info.fy_depth,
scene_info.cx_depth, scene_info.cy_depth)
points_world = transform_to_world(points_camera, frame_extrinsics(image))
points_world = points_world[projected_color_pixels_inside_mask(points_world, mask)]
all_points.append(points_world)
pcd = open3d.geometry.PointCloud(concat(all_points))
pcd = statistical_outlier_removal(pcd, nb_neighbors=35, std_ratio=1.5)
pcd = largest_dbscan_cluster(pcd, eps=0.075, min_points=15)
min_bound, max_bound = pcd.points.min(dim=0), pcd.points.max(dim=0)
return torch.cat([(min_bound + max_bound) / 2, max_bound - min_bound])3.9 Code-to-paper mapping
Code reference:
main@a8122594(2026-04-05)
| Paper Concept | Source File | Key Class/Function |
|---|---|---|
| ReAct-style TAB loop / Think-Act-Build executor | agent/loop.py | AgentLoop.run, _select_skill, _build_system_prompt, _parse_action |
| 3D-VG Skill blueprint | agent/skills/3d_visual_grounding/SKILL.md | 14-step Markdown skill pipeline |
| Tool registry | agent/tools/registry.py | ToolRegistry._register_all, get_tools_description |
| Query analysis / scene filtering / VLM scoring | agent/tools/grounding.py, agent/prompts.py | QueryParseTool, VlmFilterTool, VlmScoreTool, prompt templates |
| Reference target selection | agent/tools/grounding.py, agent/tools/sub_tools.py | ArgmaxImageAndSegIdTool, SegmentTargetInReferenceTool, vlm_identify_id, get_image_with_segment_and_marker |
| Semantic Temporal Expansion | agent/tools/grounding.py | VlmFrameExpansionTool, ExpandFromSecondaryViewTool |
| 2D mask to 3D point cloud | agent/tools/sub_tools.py | depth_to_points, generate_point_cloud, mask3d_generate_part_point_cloud |
| Semantic-Anchored Geometric Expansion | agent/tools/grounding.py | CentroidCompleteTool |
| Final bbox and proposal-assisted variant | agent/tools/grounding.py, agent/tools/sub_tools.py, eval.py | CalculateBboxTool, proposal_matching, evaluate |
| Evaluation entry points/config | scripts/eval.sh, eval.py, result_scanref.py, result_nr3d.py | env vars CLIENT_ID, SAM_CKPT, DATA_DIR, DATASET_NAME, NUM_GPUS |
4. Experimental Setup (实验设置)
Benchmarks and data scale
- ScanRefer:基于 ScanNet indoor scenes;queries 根据同类干扰物是否存在分成 Unique / Multiple;metric 为 Acc@0.25 与 Acc@0.5,即 predicted 3D box 与 ground-truth box 的 IoU 是否超过 0.25/0.5。论文说明主实验使用 VLM-Grounder / SPAZER / SeqVLM 等近期工作采用的 widely adopted subsets;released README 提供
scanref_val_250_refined.json,说明评估子集为 250 条 refined validation annotations。 - Nr3D:同样基于 ScanNet;queries 分成 Easy/Hard 与 View-Dependent/Independent;metric 为 top-1 selection accuracy。released README 提供
nr3d_val_250_refined.json,eval.py当前读取referit3d/nr3d_val_250.json;二者都指向 250 条 validation subset,refined 命名与代码路径存在轻微不一致。 - Raw visual input:每个 ScanNet video sequence 采样 300 frames(论文 §5.1;
eval.py中num_frames=300;3D-VG Skill 也写 video with ~300 frames)。TAB native setting 不输入 preprocessed scene point cloud;括号中的 3D-assisted setting 会用 Mask3D proposals 做后处理匹配。
Figure 3 解读:这张图展示作者手工修正 benchmark annotation 的三类噪声:ambiguous references、object category errors、spatial location errors。它不是方法模块本身,但会影响结果可信度:如果 query 本身指向多个合法物体或类别错误,zero-shot grounding 的误差会混入 benchmark label noise,导致模型比较不公平。
Baselines and metrics
ScanRefer 对比 fully-supervised one/two-stage 方法(ScanRefer、3DVG-T、BUTD-DETR、EDA、G3-LQ)、LLM/VLM-based supervised 方法(LLaVA-3D、Chat-Scene、SPAR-mix、VG-LLM、Video-3D-LLM、GPT4Scene、3D-RS),以及 zero-shot 方法(LLM-Grounder、ZSVG3D、SeeGround、CSVG、VLM-Grounder、SeqVLM、SPAZER)。Nr3D 对比 ReferIt3DNet、InstanceRefer、3DVG-T、EDA、BUTD-DETR、SceneVerse,以及 ZSVG3D、SeeGround、VLM-Grounder、SeqVLM、SPAZER。
Implementation and inference config
论文 §5.1 写明核心 VLM 为 Qwen3-VL-32B,foundation vision tools 为 Grounding DINO 和 SAM3,STE/MGE capped at 32 frames。released code/README 中实际可复现配置如下:
scripts/eval.sh:CLIENT_ID="your_path_to/Qwen3-VL-32B-Instruct",SAM_CKPT="your_path_to/sam3",DATA_DIR="your_path_to/data",DATASET_NAME="SCANREF"或"NR3D",NUM_GPUS=4,CUDA_VISIBLE_DEVICES=0,1,2,3 python eval.py。main.py:default seed 为3407,cache_dir='tab_workspace',device defaultcuda:0,AgentLoopmax_steps=20。agent/client.py:本地 Qwen3-VL/Qwen2.5-VL 推理使用torch.bfloat16与flash_attention_2;含视觉输入时 generation kwargs 为top_p=0.8、top_k=20、temperature=0.7、max_new_tokens=32768。agent/tools/sub_tools.py:point cloud reconstruction 默认depth_scale=1000.0,target_n=1000000;ReconstructPointCloudTool调用时设target_n=100000;SOR 参数nb_neighbors=35, std_ratio=1.5,DBSCAN 默认eps=0.075, min_points=15。
5. Experimental Results (实验结果)
Main results: ScanRefer
TAB native setting 不使用预处理点云,ScanRefer overall 达到 71.2 Acc@0.25 / 46.4 Acc@0.5;在 3D-assisted proposal matching 后为 71.6 / 61.6。相比 prior zero-shot,SPAZER 为 57.2 / 48.8,SeqVLM 为 55.6 / 49.6,VLM-Grounder 为 51.6 / 32.8。TAB 的 Acc@0.25 大幅更高,说明其 native reconstruction 能更稳定地定位目标区域;Acc@0.5 在 native setting 低于 SPAZER/SeqVLM 的部分 high-IoU numbers,但 proposal-assisted 后提升到 61.6,表明边界精度仍受 depth/segmentation 噪声影响。
| Method | Setting | Unique @0.25/@0.5 | Multiple @0.25/@0.5 | Overall @0.25/@0.5 |
|---|---|---|---|---|
| 3D-RS | supervised VLM, w/ PC | 87.4 / 77.9 | 57.0 / 50.8 | 62.9 / 56.1 |
| SPAZER | zero-shot, w/ PC | 80.9 / 72.3 | 51.7 / 43.4 | 57.2 / 48.8 |
| SeqVLM | zero-shot, w/ PC | 77.3 / 72.7 | 47.8 / 41.3 | 55.6 / 49.6 |
| VLM-Grounder | zero-shot, w/o PC | 66.0 / 29.8 | 48.3 / 33.5 | 51.6 / 32.8 |
| TAB | zero-shot, w/o PC | 90.2 / 57.6 | 60.1 / 39.9 | 71.2 / 46.4 |
| TAB + proposal match | 3D-assisted | 90.2 / 77.2 | 60.8 / 52.5 | 71.6 / 61.6 |
Main results: Nr3D
Nr3D 上 TAB native setting overall accuracy 为 68.0,超过 SPAZER 63.8 和 fully-supervised SceneVerse 64.9。尤其 Hard 为 63.2、View-Dependent 为 62.5,说明几何扩展对遮挡与视角依赖描述有帮助。括号中的 proposal-assisted 结果 overall 为 67.2,反而略低于 native 68.0,说明 Nr3D 的 top-1 selection 不一定从 proposal refinement 中受益。
| Method | Setting | Easy | Hard | Dep. | Indep. | Overall |
|---|---|---|---|---|---|---|
| SceneVerse | supervised, w/ PC | 72.5 | 57.8 | 56.9 | 67.9 | 64.9 |
| SPAZER | zero-shot, w/ PC | 68.0 | 58.8 | 59.9 | 66.2 | 63.8 |
| SeqVLM | zero-shot, w/ PC | 58.1 | 47.4 | 51.0 | 54.5 | 53.2 |
| VLM-Grounder | zero-shot, w/o PC | 55.2 | 39.5 | 45.8 | 49.4 | 48.0 |
| TAB | zero-shot, w/o PC | 72.1 | 63.2 | 62.5 | 71.4 | 68.0 |
| TAB + proposal match | 3D-assisted | 72.1 | 61.4 | 63.5 | 69.5 | 67.2 |
Ablation: STE and MGE are both necessary
Table 3 的消融直接验证 Semantic-Anchored Geometric Expansion 的两个组成部分。单帧 reconstruction(无 STE、无 MGE)在 ScanRefer overall @0.25 只有 41.6,Nr3D overall 52.0;只加 MGE 但不加 STE 时,ScanRefer overall @0.25 提升到 50.0,但 Nr3D Dep. 只有 48.9,说明单帧 centroid 偏差会污染投影;只加 STE 但不加 MGE 时,ScanRefer overall @0.25 为 58.0,Nr3D overall 59.2,说明纯语义 tracking 仍覆盖不足;二者都启用时达到 71.2 / 46.4 与 68.0。
| Variant | STE | MGE | ScanRefer Overall @0.25/@0.5 | Nr3D Overall |
|---|---|---|---|---|
| (a) single-frame | ✗ | ✗ | 41.6 / 22.8 | 52.0 |
| (b) no STE | ✗ | ✓ | 50.0 / 29.2 | 55.1 |
| (c) no MGE | ✓ | ✗ | 58.0 / 36.0 | 59.2 |
| (d) full TAB | ✓ | ✓ | 71.2 / 46.4 | 68.0 |
Figure 4 解读:完整 TAB 的 predicted box IoU 为 ;去掉 MGE 后,agent 只能依赖 VLM-tracked frames,点云覆盖不完整,IoU 降到 ;去掉 STE 后,centroid 来自单帧,受局部深度和遮挡偏差影响,IoU 为 。这张 qualitative comparison 与 Table 3 对应:STE 负责让 centroid 起点可靠,MGE 负责让最终多视角覆盖完整。
Overall conclusion and limitations
总体结论是:TAB 在不输入预处理点云的 zero-shot setting 下,把 3D-VG 从 proposal matching 改写为 agentic semantic reasoning + deterministic geometry reconstruction,ScanRefer/Nr3D 都达到或超过当时强 zero-shot 与部分 supervised baselines。最有说服力的证据不是单个表格分数,而是 native no-PC setting、proposal-assisted setting 与 ablation 三者之间的关系:native setting 已能粗准定位;proposal matching 主要提升 ScanRefer high-IoU boundary precision;STE/MGE 分别控制 centroid quality 和 multi-view coverage。
作者没有单列 Limitations 小节。按方法假设与 released code,可读出的边界是:TAB 依赖 RGB-D sequence、可靠 camera intrinsics/extrinsics 和 depth maps;VLM/SAM3 的误检会影响 reference selection;MGE 的 Z-buffer 检查依赖 depth tolerance ,面对透明/反光/薄物体或严重 depth noise 时可能不稳;released repo 当前公开脚本中的 frame cap、coarse detector 实现与论文文字不完全一致,复现实验时需要固定 commit 并记录配置。