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.

KC-3D (Kinetics Change 3D) is a real-world indoor change detection dataset that pairs RGB images of the same scene captured from different viewpoints, together with depth maps, change-region masks, and ground-truth camera calibration data. It is used exclusively as a test benchmark for CYWS-3D — the loader exposes only the test split, making it straightforward to run evaluation without accidentally training on held-out data.

Download

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

Structure

After extraction the dataset has the following layout:
kc3d/
├── data_split.pkl          # Train / val / test scene lists
├── <scene_id>/
│   ├── image1.png          # First RGB view
│   ├── image2.png          # Second RGB view
│   ├── depth1.tiff         # Depth map for image1
│   ├── depth2.tiff         # Depth map for image2
│   ├── mask1.png           # Change region mask for image1
│   ├── mask2.png           # Change region mask for image2
│   └── <prefix>.npy        # Camera parameters (intrinsics, position, rotation)
└── ...
data_split.pkl is a pickled dictionary with "train", "val", and "test" keys. Each key maps to a list of scene descriptors. The KC3D loader indexes only into the test split, so the training scenes are never returned by __getitem__. Depth maps are stored as floating-point .tiff files, one per view per scene. They share the spatial dimensions of the corresponding RGB images. Camera parameter files (.npy) are named by joining the first three underscore-separated tokens of the image filename stem, e.g. scene_001_view.npy. Each file contains a dictionary with intrinsics, position, and rotation entries. Change masks are single-channel .png files that mark the pixels belonging to changed objects. They are used to derive bounding-box annotations (target1, target2) returned by the loader.
KC-3D exposes only the test split at inference time. If you iterate over a DataLoader built from KC3D, every sample belongs to the held-out test set, which makes the dataset suitable for rigorous, unbiased evaluation.

Using the Dataset Loader

The KC3D class lives in datasets/kc3d.py. Pass the path to the extracted directory and choose whether to load ground-truth camera registration data.
from torch.utils.data import DataLoader
from einops import rearrange
from datasets.kc3d import KC3D


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 camera parameters ──────────────────────────────────
dataset_no_gt = KC3D(
    path_to_dataset="/data/kc3d",
    use_ground_truth_registration=False,
)

loader_no_gt = DataLoader(
    dataset_no_gt,
    batch_size=4,
    shuffle=False,
    collate_fn=collate_fn,
)

for batch in loader_no_gt:
    # Available keys: image1, image2, target1, target2, registration_strategy
    images1 = batch["image1"]   # (B, C, H, W) float tensor
    images2 = batch["image2"]
    targets1 = batch["target1"] # list of bbox lists
    break


# ── With ground-truth camera parameters ─────────────────────────────────────
dataset_gt = KC3D(
    path_to_dataset="/data/kc3d",
    use_ground_truth_registration=True,
)

loader_gt = DataLoader(
    dataset_gt,
    batch_size=4,
    shuffle=False,
    collate_fn=collate_fn,
)

for batch in loader_gt:
    # All keys above, plus depth maps and camera parameters
    depth1 = batch["depth1"]          # (B, H, W) float tensor
    intrinsics1 = batch["intrinsics1"]  # (B, 3, 3) tensor
    position1 = batch["position1"]    # (B, 3) tensor
    rotation1 = batch["rotation1"]    # (B, 3, 3) tensor
    break
Set use_ground_truth_registration=True when you want the model to perform precise 3D-warping alignment using the known camera geometry. Set it to False when benchmarking a purely appearance-based or estimated-pose pipeline.

Batch Fields

The table below lists every key that may appear in a batch dictionary. Keys marked conditional are only present when use_ground_truth_registration=True.
FieldType / ShapeDescription
image1FloatTensor (B, C, H, W)First RGB view, values in [0, 1]
image2FloatTensor (B, C, H, W)Second RGB view, values in [0, 1]
depth1FloatTensor (B, H, W)Depth map for image1, loaded from .tiffconditional
depth2FloatTensor (B, H, W)Depth map for image2, loaded from .tiffconditional
intrinsics1FloatTensor (B, 3, 3)Camera intrinsic matrix for view 1 — conditional
intrinsics2FloatTensor (B, 3, 3)Camera intrinsic matrix for view 2 — conditional
position1FloatTensor (B, 3)World-space camera position for view 1 — conditional
position2FloatTensor (B, 3)World-space camera position for view 2 — conditional
rotation1FloatTensor (B, 3, 3)Rotation matrix for view 1 — conditional
rotation2FloatTensor (B, 3, 3)Rotation matrix for view 2 — conditional
target1list[list[float]]Change bounding boxes for view 1, each as [x1, y1, x2, y2]
target2list[list[float]]Change bounding boxes for view 2, each as [x1, y1, x2, y2]
registration_strategylist[str]Always "3d" for every KC-3D sample
target1 and target2 are kept as plain Python lists (not stacked tensors) by collate_fn because the number of bounding boxes may differ between scenes. The registration_strategy list is similarly left un-stacked.

Build docs developers (and LLMs) love