# BSS (Benchmark Storage Structure) Format: Complete Guide to the LingBot-Map Standard

> Learn the BSS format, a standardized on-disk layout for RGB frames, depth maps, camera intrinsics, and poses. Discover how LingBot-Map uses BSS for dataset-agnostic 3D reconstruction evaluation.

- Repository: [Robbyant/lingbot-map](https://github.com/Robbyant/lingbot-map)
- Tags: api-reference
- Published: 2026-07-08

---

**The BSS (Benchmark Storage Structure) format is a standardized on-disk layout used by the LingBot-Map benchmark pipeline to store RGB frames, depth maps, camera intrinsics, and poses in a unified directory structure, enabling dataset-agnostic evaluation of 3D reconstruction methods.**

The BSS format serves as the universal data interface for the Robbyant/lingbot-map repository. It abstracts away dataset-specific variations by enforcing a consistent file organization that any raw collection can be converted into, allowing benchmark tools to uniformly load scenes without modification.

## Directory Structure and File Organization

### Standard BSS Layout (v2)

A BSS artifact is a single directory containing all per-scene data. The typical structure follows this pattern:

```

/path/to/bss_workspace/
│
└─ scene_name/                     # A BSS artifact

   │
   ├─ rgb/                         # JPEG/PNG files per frame (e.g., 000000.jpg)

   ├─ depth/                       # 16-bit PNG or .npy depth maps

   ├─ intrinsics.txt               # One line per frame: fx fy cx cy width height

   ├─ trajectory.txt               # One line per frame: 3×4 C2W pose matrix

   ├─ mask/ (optional)             # Binary masks for sky segmentation

   └─ meta.yaml (optional)        # Scene metadata and description

```

### Data File Specifications

**Image files** in the `rgb/` directory store raw RGB frames using zero-padded indices to maintain lexicographical order. **Depth files** in `depth/` store per-pixel depth using matching filenames, typically as 16-bit PNG or NumPy `.npy` files.

The **intrinsics.txt** implementation in [`benchmark/benchmark/io/intrinsics.py`](https://github.com/Robbyant/lingbot-map/blob/main/benchmark/benchmark/io/intrinsics.py) defines a plain-text table where each line corresponds to a frame and lists focal lengths (fx, fy), principal point (cx, cy), and image dimensions (width, height). The **trajectory.txt** implementation in [`benchmark/benchmark/io/trajectory.py`](https://github.com/Robbyant/lingbot-map/blob/main/benchmark/benchmark/io/trajectory.py) stores camera-to-world poses in row-major format, with each line containing a flattened 3×4 rotation-translation matrix.

## Core Python Classes for BSS Access

### BSSArtifact: Scene Container

The `BSSArtifact` class, defined in [`benchmark/core/storage.py`](https://github.com/Robbyant/lingbot-map/blob/main/benchmark/core/storage.py), represents a single BSS artifact on disk. It holds the filesystem path to a scene folder and provides helper methods to resolve standardized file names for images, depth maps, and calibration files.

### BSSLoader: Data I/O Interface

Located in [`benchmark/core/loader.py`](https://github.com/Robbyant/lingbot-map/blob/main/benchmark/core/loader.py), the `BSSLoader` class consumes a `BSSArtifact` and handles the actual loading of data into PyTorch tensors. It supports optional context resizing for down-sampling large inputs during benchmark runs and provides a unified interface for accessing frames by index. The [`benchmark/run.py`](https://github.com/Robbyant/lingbot-map/blob/main/benchmark/run.py) script leverages these classes as the main entry point for loading scenes, running reconstruction methods, and writing results back into BSS format.

## Loading and Iterating Over BSS Data

To load a specific frame from a BSS directory, instantiate an artifact and loader, then call the appropriate loading methods:

```python
from benchmark.core.storage import BSSArtifact
from benchmark.core.loader import BSSLoader

# Initialize the artifact pointing to a BSS scene

artifact = BSSArtifact("/path/to/bss_workspace/scene_01")

# Create loader with optional 0.5x down-sampling

loader = BSSLoader(artifact, resize_context=0.5)

# Load frame at index 0

rgb = loader.load_image(0)          # Returns torch.Tensor (C×H×W)

depth = loader.load_depth(0)        # Returns torch.Tensor (1×H×W)

intrinsics = loader.load_intrinsics(0)  # Returns 3×3 matrix

pose_c2w = loader.load_pose(0)      # Returns 4×4 homogeneous matrix

```

For batch processing or evaluation loops, iterate over all frames using the `num_frames` attribute:

```python
num_frames = loader.num_frames

for idx in range(num_frames):
    rgb = loader.load_image(idx)
    depth = loader.load_depth(idx)
    pose = loader.load_pose(idx)
    # Process frame for reconstruction or evaluation

```

## Converting Raw Datasets to BSS Format

### Using prepare.py

The [`benchmark/prepare.py`](https://github.com/Robbyant/lingbot-map/blob/main/benchmark/prepare.py) script converts arbitrary raw datasets into the BSS layout. This utility reads the original dataset format, writes the required directory tree, and generates the [`intrinsics.txt`](https://github.com/Robbyant/lingbot-map/blob/main/intrinsics.txt) and [`trajectory.txt`](https://github.com/Robbyant/lingbot-map/blob/main/trajectory.txt) files in v2 format.

Execute the conversion from the command line:

```bash
python benchmark/prepare.py \
    --raw_root /path/to/raw_dataset \
    --bss_workspace /path/to/bss_workspace \
    --dataset_name my_dataset

```

After conversion, the resulting BSS workspace can be consumed immediately by `BSSLoader` and the benchmark evaluation scripts.

## Summary

- The **BSS format** standardizes on-disk storage for RGB images, depth maps, camera intrinsics, and poses in a single directory per scene.
- **Required files** include `rgb/`, `depth/`, [`intrinsics.txt`](https://github.com/Robbyant/lingbot-map/blob/main/intrinsics.txt), and [`trajectory.txt`](https://github.com/Robbyant/lingbot-map/blob/main/trajectory.txt), with optional `mask/` and [`meta.yaml`](https://github.com/Robbyant/lingbot-map/blob/main/meta.yaml) for additional metadata.
- The **`BSSArtifact`** class in [`benchmark/core/storage.py`](https://github.com/Robbyant/lingbot-map/blob/main/benchmark/core/storage.py) provides filesystem abstraction for scene directories.
- The **`BSSLoader`** class in [`benchmark/core/loader.py`](https://github.com/Robbyant/lingbot-map/blob/main/benchmark/core/loader.py) handles tensor loading and optional resizing.
- The **[`prepare.py`](https://github.com/Robbyant/lingbot-map/blob/main/prepare.py)** script enables conversion from arbitrary raw datasets to the BSS layout.

## Frequently Asked Questions

### What file types does BSS support for depth maps?

The BSS format accepts depth maps as **16-bit PNG images** or **NumPy `.npy` files**. Both formats store per-pixel depth values using the same zero-padded indexing scheme as the corresponding RGB images in the `rgb/` directory.

### How are camera poses stored in the BSS format?

Camera poses are stored in [`trajectory.txt`](https://github.com/Robbyant/lingbot-map/blob/main/trajectory.txt) using the **camera-to-world (C2W) convention**. Each line contains a flattened 3×4 matrix in row-major order, representing the rotation matrix followed by the translation vector. The loader automatically converts these to 4×4 homogeneous transformation matrices when calling `load_pose()`.

### Can I use BSS with custom datasets not originally in the LingBot-Map repository?

Yes. The BSS format is **deliberately dataset-agnostic**. You can convert any raw dataset containing images, depth, and pose information using the [`benchmark/prepare.py`](https://github.com/Robbyant/lingbot-map/blob/main/benchmark/prepare.py) script, or manually create the directory structure and text files following the v2 specification. Once organized as BSS, the data integrates seamlessly with the benchmark pipeline.

### What is the difference between BSSArtifact and BSSLoader?

**`BSSArtifact`** is a lightweight path container that knows where files are located on disk, while **`BSSLoader`** performs the actual I/O operations. The artifact resolves filenames according to the BSS specification, and the loader reads those files into memory as PyTorch tensors, handling format conversions and optional resizing.