feat(scenegraph): add SceneGraphBuilder for pipeline-driven graph construction

Introduce SceneGraphBuilder + SceneGraphBuildConfig to decouple scene graph
construction from the verification notebook. The builder handles batch
inference, hash encoding, and object node creation internally.

- Add SceneGraphBuilder.build_from_room_views() as the main entry point
- Add SceneGraphBuildConfig for inference_batch_size and position strategy
- Add SceneGraphBuildArtifacts to carry cropped images and debug metadata
- Extend ObjectNode with optional detection metadata (label, confidence,
  bbox_xyxy, source_view_id, position_confidence)
- Add RoomView frozen dataclass as a structured view container
- Add flatten_room_views() utility to replace inline list comprehensions
- Refactor notebooks/verification.py to use the new builder API

BREAKING CHANGE: ObjectNode now accepts additional optional fields; direct
scene_graph.objects[obj_id] = ObjectNode(...) construction in the notebook
is replaced by builder.build_from_room_views(...).
This commit is contained in:
2026-05-30 15:40:58 +08:00
parent 97e53d44f8
commit a127032e18
8 changed files with 910 additions and 129 deletions

View File

@@ -5,10 +5,17 @@ from .habitat import (
)
from .image_save import save_object_image, save_room_view
from .topdown import TopDownRenderStyle, TopDownSceneElements, render_topdown_scene_map
from .views import RoomViewsByRoom, collect_room_views_by_room, collect_scene_images
from .views import (
RoomView,
RoomViewsByRoom,
collect_room_views_by_room,
collect_scene_images,
flatten_room_views,
)
__all__ = [
"HabitatSimulatorConfig",
"RoomView",
"RoomViewsByRoom",
"TopDownRenderStyle",
"TopDownSceneElements",
@@ -16,6 +23,7 @@ __all__ = [
"collect_room_views_by_room",
"collect_scene_images",
"create_habitat_simulator",
"flatten_room_views",
"render_topdown_scene_map",
"save_object_image",
"save_room_view",

View File

@@ -1,5 +1,6 @@
from __future__ import annotations
from dataclasses import dataclass, field
from importlib import import_module
from pathlib import Path
from typing import Any, Callable, Iterable, Sequence
@@ -11,6 +12,24 @@ RoomViewsByRoom = dict[str, list[Any]]
ProgressTrack = Callable[[Iterable[Any], str], Iterable[Any]]
@dataclass(frozen=True)
class RoomView:
room_id: str
view_idx: int
rgb: Any = field(compare=False)
depth: Any | None = field(default=None, compare=False)
agent_position: np.ndarray | None = field(default=None, compare=False)
agent_rotation: Any | None = field(default=None, compare=False)
def flatten_room_views(room_views_by_room: RoomViewsByRoom) -> list[RoomView]:
result: list[RoomView] = []
for room_id, views in room_views_by_room.items():
for idx, rgb in enumerate(views):
result.append(RoomView(room_id=room_id, view_idx=idx, rgb=rgb))
return result
def collect_room_views_by_room(
agent: Any,
sim: Any,