Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ragavsachdeva/CYWS-3D/llms.txt

Use this file to discover all available pages before exploring further.

RC-3D (Rendered Change 3D) is a large-scale synthetic dataset of rendered indoor scenes organised as image triplets: a before frame, a during-change frame, and an after frame. CYWS-3D uses the before frame (image1) and the after frame (image2) as the pair to compare, skipping the intermediate frame. The dataset is split into four parts (part1part4), each with its own COCO-format annotation file, and the RC3D() factory function returns a single ConcatDataset that joins all four parts for seamless iteration.

Download

Fetch the archive with wget and extract it into a local directory:
wget https://thor.robots.ox.ac.uk/cyws-3d/rc3d.tar
tar -xf rc3d.tar

Structure

After extraction the dataset is organised as four sibling directories:
rc3d/
├── part1/
│   ├── coco_annotations.json   # Image list + change bounding-box annotations
│   ├── <image_name>.jpg        # RGB frames (before / during / after triplets)
│   └── depth_<image_stem>.png  # Ground-truth depth map per frame (optional)
├── part2/
│   └── ...
├── part3/
│   └── ...
└── part4/
    └── ...
Image triplets — within each part’s coco_annotations.json, images are stored in groups of three. Index 0 of each triplet is the before frame (image1), index 1 is the during-change frame (unused by the loader), and index 2 is the after frame (image2). The SubDataset loader therefore reads every third image starting at offset 0 for image1 and every third image starting at offset 2 for image2. coco_annotations.json follows the standard COCO layout with "images" and "annotations" top-level keys. Bounding boxes are stored in COCO format [x, y, w, h]; the loader converts them to [x1, y1, x2, y2] before returning them. Depth maps are single-channel PNG files located alongside the RGB images. The filename convention is depth_<image_basename>.png, where <image_basename> is the image filename without the .jpg extension. Depth loading is gated by the use_gt_depth flag.
COCO annotations store bounding boxes as [x, y, width, height]. The RC-3D loader automatically converts these to corner format [x1, y1, x2, y2] before returning them in target1 and target2, so no manual conversion is needed in your training loop.

Using the Dataset Loader

The RC3D factory function and SubDataset class live in datasets/rc3d.py. RC3D() instantiates one SubDataset per part and wraps them in a ConcatDataset, so you interact with a single unified dataset object.
from torch.utils.data import DataLoader
from einops import rearrange
from datasets.rc3d import RC3D


def collate_fn(batch):
    keys = batch[0].keys()
    collated = {}
    for key in keys:
        collated[key] = [item[key] for item in batch]
        if "target" in key or "registration" in key:
            continue
        collated[key] = rearrange(collated[key], "... -> ...")
    return collated


# ── Without ground-truth depth ───────────────────────────────────────────────
dataset_no_depth = RC3D(
    path_to_dataset="/data/rc3d",
    use_gt_depth=False,
)

loader_no_depth = DataLoader(
    dataset_no_depth,
    batch_size=8,
    shuffle=True,
    collate_fn=collate_fn,
)

for batch in loader_no_depth:
    # Available keys: image1, image2, target1, target2, registration_strategy
    images1 = batch["image1"]   # (B, C, H, W) float tensor — "before" frame
    images2 = batch["image2"]   # (B, C, H, W) float tensor — "after" frame
    targets1 = batch["target1"] # list of single-bbox lists [[x1, y1, x2, y2], ...]
    break


# ── With ground-truth depth ──────────────────────────────────────────────────
dataset_depth = RC3D(
    path_to_dataset="/data/rc3d",
    use_gt_depth=True,
)

loader_depth = DataLoader(
    dataset_depth,
    batch_size=8,
    shuffle=True,
    collate_fn=collate_fn,
)

for batch in loader_depth:
    # All keys above, plus depth maps
    depth1 = batch["depth1"]  # (B, H, W) tensor — depth for the "before" frame
    depth2 = batch["depth2"]  # (B, H, W) tensor — depth for the "after" frame
    break
Because RC3D() returns a ConcatDataset, you can pass it directly to a DataLoader exactly like any other PyTorch Dataset. The total length is the sum of sample counts across all four parts.
image1 always corresponds to the before frame (triplet index 0) and image2 to the after frame (triplet index 2). The intermediate during-change frame is never loaded by the dataset, so the ConcatDataset length equals the total number of triplets across all four parts, not the total number of individual images.

Batch Fields

The table below lists every key that may appear in a batch dictionary returned by collate_fn. Keys marked conditional are only present when use_gt_depth=True.
FieldType / ShapeDescription
image1FloatTensor (B, C, H, W)”Before” RGB frame (triplet index 0), values in [0, 1]
image2FloatTensor (B, C, H, W)”After” RGB frame (triplet index 2), values in [0, 1]
depth1FloatTensor (B, H, W)Depth map for image1, loaded from depth_<stem>.pngconditional
depth2FloatTensor (B, H, W)Depth map for image2, loaded from depth_<stem>.pngconditional
target1list[list[float]]Single change bbox for view 1 as [[x1, y1, x2, y2]] (converted from COCO format)
target2list[list[float]]Single change bbox for view 2 as [[x1, y1, x2, y2]] (converted from COCO format)
registration_strategylist[str]Always "3d" for every RC-3D sample
Unlike KC-3D, RC-3D provides no ground-truth camera intrinsics, position, or rotation matrices. The 3D registration used by CYWS-3D on this dataset relies on the depth maps together with the model’s internal correspondence estimation rather than explicit camera parameters.

Build docs developers (and LLMs) love