3D-Mem: 3D Scene Memory Framework

repository·main·Indexed 42 days ago

https://github.com/umass-embodied-agi/3d-mem

A framework for 3D Scene Memory designed for embodied exploration and reasoning, accepted to CVPR 2025. It includes tools for evaluating embodied agents on A-EQA and GOAT-Bench benchmarks, as well as a CF-SLAM batch processing pipeline for modeling Grounded SAM detections in 3D using spatial and visual similarities.

Tokens
12.3K
Snippets
38
Records
50
Agent score
54%

What's inside 3D-Mem

  1. Run evaluation on A-EQA

    main

    To generate predictions for the A-EQA dataset, use the run_aeqa_evaluation.py script with a configuration file. You can split tasks into ranges using --start_ratio and --end_ratio (values between 0.0 and 1.0). Results from all splits are automatically aggregated and saved upon completion.

    To evaluate the first half of the dataset, use:

    python run_aeqa_evaluation.py -cf cfg/eval_aeqa.yaml --start_ratio 0.0 --end_ratio 0.5
    python run_aeqa_evaluation.py -cf cfg/eval_aeqa.yaml
  2. Prepare datasets and OpenAI API for evaluation

    main

    Before running evaluations, you must configure the datasets and API access:

    1. HM3D Dataset: Download the train and val splits of HM3D. In cfg/eval_aeqa.yaml and cfg/eval_goatbench.yaml, set the scene_data_path to the directory containing your train/ and val/ folders.
    2. Question Files: The repository includes test questions in the data/ folder.
      • For A-EQA: aeqa_questions-41.json (small subset) and aeqa_questions-184.json (official subset).
      • For GOAT-Bench: The complete val_unseen split is included.
    3. OpenAI API: Configure your OpenAI API endpoint and key in src/const.py.
  3. Run evaluation on GOAT-Bench

    main

    To run the GOAT-Bench evaluation, use the run_goatbench_evaluation.py script.

    Key Options:

    • -cf: Path to the configuration file (e.g., cfg/eval_goatbench.yaml).
    • --start_ratio / --end_ratio: Split tasks into ranges.
    • --split: Specify the episode to evaluate for each scene. Note that by default, only the first episode is tested due to resource constraints, even though GOAT-Bench provides 10 episodes per scene.

    Results are printed and saved automatically after the script finishes.

    python run_goatbench_evaluation.py -cf cfg/eval_goatbench.yaml
  4. Install 3D-Mem via Conda and Pip

    main

    To use 3D-Mem, set up a Python 3.9 environment on Linux using Conda and install the required dependencies including PyTorch, Habitat-Sim, PyTorch3D, and several vision/ML libraries.

    Follow these steps to create the environment and install the packages:

    # Create and activate the conda environment
    conda create -n 3dmem python=3.9 -y && conda activate 3dmem
    
    # Install PyTorch with CUDA 11.8 support
    pip install torch==2.0.1 torchvision==0.15.2 --index-url https://download.pytorch.org/whl/cu118
    
    # Install Habitat-Sim and Faiss
    conda install -c conda-forge -c aihabitat habitat-sim=0.2.5 headless faiss-cpu=1.7.4 -y
    
    # Install PyTorch3D
    conda install https://anaconda.org/pytorch3d/pytorch3d/0.7.4/download/linux-64/pytorch3d-0.7.4-py39_cu118_pyt201.tar.bz2 -y
    
    # Install remaining dependencies
    pip install omegaconf==2.3.0 open-clip-torch==2.26.1 ultralytics==8.2.31 supervision==0.21.0 opencv-python-headless==4.10.* \
     scikit-learn==1.4 scikit-image==0.22 open3d==0.18.0 hipart==1.0.4 openai==1.35.3 httpx==0.27.2
  5. Find observation points for snapshots

    main

    These functions help determine optimal camera positions to observe objects or groups of objects in a scene, ensuring the camera is placed in unoccupied (navigable) space and has a clear line of sight.

    get_proper_snapshot_observation_point

    Finds a single optimal observation point for a set of object centers. It uses the structure tensor of the object centers to determine the 'long axis' and 'short axis' of the group, then attempts to place the camera opposite the short axis to capture the group effectively.

    get_random_snapshot_observation_point

    Similar to the above, but selects an observation point randomly from valid unoccupied candidates, weighted by their position relative to the object group's orientation.

    Common Parameters:

    • obj_centers: [N, 2] array of object centers in voxel space.
    • unoccupied_map: [H, W] boolean array where True indicates navigable space.
    • min_obs_dist / max_obs_dist: Distance range from the object center to the camera.
    • snapshot_observation_point: A fallback/initial point for the observation.

    Returns: A [2] array representing the optimal (or fallback) observation point in voxel coordinates.

  6. Data structures: Frontier, SnapShot, and SceneGraphItem

    main

    The TSDFPlanner uses several dataclasses to manage exploration and semantic data:

    • Frontier: Represents an unexplored region.

      • position: np.ndarray (voxel grid coordinates).
      • orientation: np.ndarray (directional vector).
      • region: np.ndarray (boolean mask of the voxel grid).
      • frontier_id: int.
      • image: str (path to snapshot image).
      • target_detected: bool.
      • feature: torch.Tensor (image features).
    • SnapShot: Represents a semantic observation of a cluster of objects.

      • image: str (path to image).
      • color: Tuple[float, float, float].
      • obs_point: np.ndarray (voxel grid position).
      • full_obj_list: Dict[int, float] (object ID to confidence).
      • cluster: List[int] (list of object IDs).
      • position: np.ndarray (calculated center).
    • SceneGraphItem: Represents a detected object in the scene.

      • object_id: int.
      • bbox_center: np.ndarray.
      • confidence: float.
      • image: str.
  7. Configure visualization saving

    main

    By default, the evaluation configuration saves visualization results, including:

    • Topdown maps
    • Egocentric views
    • Memory snapshots
    • Frontier snapshots at each step

    Performance Note: Saving visualizations significantly slows down the evaluation process. For large-scale evaluations, set save_visualization to false in your configuration file.

  8. Use OptionalWandB for flexible logging

    main

    The OptionalWandB class is a singleton wrapper designed to allow your code to use wandb methods (like .init(), .log(), and .finish()) without requiring the wandb library to be installed or enabled.

    If wandb is installed and enabled via configuration, OptionalWandB acts as a proxy, forwarding calls to the actual wandb library. If wandb is missing or disabled, the calls are silently ignored (or logged as debug messages), preventing ImportError or runtime crashes.

    Implementation Pattern

    1. In your main script: Instantiate the singleton and configure it using .set_use_wandb(bool) based on your project settings.
    2. In utility or secondary scripts: Instantiate the singleton to get the same instance, but do not call .set_use_wandb() again; it will inherit the state set by the main script.
    from custom_wandb import OptionalWandB
    
    # 1. Setup in main script
    owandb = OptionalWandB()
    owandb.set_use_wandb(True)  # or cfg.use_wandb
    
    # 2. Use like normal wandb
    owandb.init(project="my_project")
    owandb.log({"metric": 42})
    owandb.finish()
  9. Run the CF-SLAM Batch Processing Pipeline

    main

    The cfslam_pipeline_batch.py script models Grounded SAM detections in 3D. It requires a dataset with CLIP features saved for each object/mask and assumes tag2text classes are available. The pipeline is managed via Hydra and processes a sequence of frames to build a 3D map of objects.

    To run the pipeline, use the main function (which is decorated with @hydra.main). You will need to provide a configuration file (defaulting to ../configs/slam_pipeline/base.yaml) and specify dataset parameters via the Hydra CLI or config files.

    # Example command (assuming hydra configuration is set up)
    python src/conceptgraph/slam/cfslam_pipeline_batch.py dataset_root=/path/to/data dataset_config=/path/to/config.yaml
  10. Configure CF-SLAM Data Saving and Visualization

    main

    Use the following configuration keys to control output and rendering:

    • save_objects_all_frames: If True, saves the state of objects for every frame in a folder named objects_all_frames within the scene directory.
    • save_pcd: If True, saves the full point cloud as a .pkl.gz file. It saves both the raw and the post-processed versions.
    • vis_render: If True, enables online object rendering for visualization.
    • render_camera_path: Path to the pinhole camera parameters for rendering.
    • debug_render: If True, opens an interactive Open3D visualization window during the process.
    • class_agnostic: If True, colors objects by instance; otherwise, colors them by their most common classes.
    • obj_min_detections: Minimum number of detections required for an object to be included in saved visualizations/outputs.
    • skip_bg: If True, skips background detection (e.g., wall, floor, ceiling).
  11. Configure CF-SLAM Matching and Similarity

    main

    The object association logic in the pipeline is controlled by several configuration keys:

    • match_method: The method used to compute object association. Currently supports sim_sum.
    • phys_bias: A bias factor used in the sim_sum method to weight spatial vs visual similarities. Formula: (1 + phys_bias) * spatial_sim + (1 - phys_bias) * visual_sim.
    • sim_threshold: The minimum similarity score required to associate a detection with an existing object.
    • use_contain_number: If True, uses 2D bounding box containment information to refine associations.
    • contain_area_thresh: Threshold for determining if a box is contained within another.
    • contain_mismatch_penalty: A penalty subtracted from the aggregate similarity if there is a mismatch in containment status between a detection and an object.
  12. Merge detected objects into the map

    main

    Updates the existing map by either adding new detections as new objects or merging detections into existing objects based on match indices.

    Args:

    • detection_list: DetectionList of new detections.
    • objects: MapObjectList of current map objects.
    • match_indices: A list where each entry is the index of the existing object a detection matches with, or None if it is a new object.
    • downsample_voxel_size: Voxel size for processing.
    • dbscan_remove_noise: Boolean to enable/disable DBSCAN noise removal.
    • dbscan_eps: DBSCAN epsilon parameter.
    • dbscan_min_points: DBSCAN minimum points parameter.
    • spatial_sim_type: The type of spatial similarity to use during merging.
    • device: The compute device (e.g., 'cpu' or 'cuda').

    Returns an updated MapObjectList.

    updated_objects = merge_obj_matches(
        detection_list=detections,
        objects=current_objects,
        match_indices=matches,
        downsample_voxel_size=0.05,
        dbscan_remove_noise=True,
        dbscan_eps=0.02,
        dbscan_min_points=10,
        spatial_sim_type="iou",
        device="cuda"
    )