projectsidewalk/rampnet-crop-model-dataset-round1

Dataset

RampNet Crop-Model Dataset — Round 1 (Project Sidewalk crops)

0

3 commits

1 linked in READMEs

updated Aug 6, 2026

See the code

README

RampNet Crop-Model Dataset — Round 1 (Project Sidewalk crops)

The training data behind round 1 of the RampNet Stage 1 crop model — 27,704 crops, 13.37 GB — from RampNet: A Two-Stage Pipeline for Bootstrapping Curb Ramp Detection in Streetscape Images from Open Government Metadata (O'Meara et al., ICCV'25 CV4A11y workshop, arXiv:2508.09415).

The crop model is what turns a government curb ramp GPS coordinate into a pixel keypoint on a panorama; every label in rampnet-dataset was placed by it. It is trained in two rounds:

rounddatawhere
1Project Sidewalk cropsthis repo
2manually labeled cropsrampnet-crop-model-dataset-round2

The resulting checkpoints are at rampnet-crop-model.

Why this needed publishing

It cannot be regenerated. stage_one/crop_model/ps_model/data/download_data.py fetches from the live Project Sidewalk servers with no snapshot pinning, and those databases keep growing — so re-running it today builds a different training set, not this one. The same is true of the train/val/test partition: splititup.sh shuffles with shuf and no seed, so the 70/15/15 split here is not reproducible either. Both are reasons to ship the artifact rather than instructions.

How these crops were made

Every step below is download_data.py; the constants live in that script, not in a config.

  1. Source labels. Crowdsourced curb ramp labels fetched live from 12 Project Sidewalk deployments (Seattle, Chicago, Pittsburgh, St. Louis, Columbus, Knoxville, Newberg, Oradell, Teaneck, Cliffside Park, Mendota, Blackhawk Hills), keeping only CurbRamp labels whose crowd validation satisfies Agree − Disagree ≥ 2.
  2. Panorama fetch. Each label's GSV panorama is downloaded as zoom-4 tiles, assembled, trimmed, and resized to an 8192×4096 equirectangular.
  3. Projection. The label's panorama x becomes a yaw angle, snapped to the nearest 30° (so there are 12 possible camera headings per panorama). A perspective view is rendered at FOV 90°, pitch −30° (looking down at the street corner), 2048×2048 — and only the central horizontal third is kept: columns int(2048/3) to int(2048·2/3), which is where the 683×2048 shape comes from (≈37° effective horizontal field of view).
  4. Keypoints. The anchor label plus every other validated label on the same panorama is projected into that view with the matching point transform; neighbours landing inside the strip are appended to the filename. Each keypoint is the projection of the label's stored Project Sidewalk panorama coordinate — no re-annotation happened at crop time. The 30° yaw snap keeps the anchor within ~±15° of the view axis, which guarantees it lands inside the strip: that is why no crop in this set is empty.
  5. Naming and split. Filenames get a fresh random 8-character uid (see crop_uid below) plus the point list; splititup.sh then makes the unseeded 70/15/15 partition.

Contents

columnmeaning
crop_idthe original filename stem
crop_uidthe opaque 8-character token the filename starts with — not a panorama id
imagethe crop, stored as the exact source bytes — 683×2048 JPEG, not re-encoded
keypointslist of {x, y} curb ramp locations
n_keypointshow many
width, heightpixel dimensions as stored
sha256hash of the exact bytes

27,704 crops carry 35,757 keypoints between them. There are no negative crops in this round: every crop carries at least one keypoint, so a model trained on this set alone never sees an empty example.

keypoints in a cropcrops
121,751
24,629
3840
4293
5106
677
74
94

The keypoints were hiding in the filenames

In the original dataset the labels are encoded in the filename and parsed at load time: 007mz25c_-_118_596_-_478_611.jpg carries keypoints (118, 596) and (478, 611). Here they are a real column.

crop_uid is not a panorama id, and the panorama is not recoverable

The leading token looks like an id you could join on. It is not one. download_data.py:277 builds each filename with random.choices(alphabet, k=8), so the token is freshly random per crop and the Project Sidewalk panorama it was cut from is not stored anywhere in this artifact. Every one of the 27,704 crops has a distinct token, so nothing collided — but that is a property of this draw, not a guarantee. If you need crop → panorama provenance, it is not here.

The x axis carries a 3.1% label/image mismatch

Coordinates are stored verbatim, in the pixel space of the stored crop (683×2048), and are deliberately not normalised — because normalising would force a choice about the following, and that choice belongs to you.

train.py resizes every crop with transforms.Resize((1024, 352)) and scales both keypoint axes by 0.5:

axisimage scalekeypoint scaleagree?
y2048 → 1024 = 0.50.5yes
x683 → 352 = 0.51540.5no — off by 3.1%

So y is consistent and x is under-scaled: in the resized 352-px-wide crop a label drifts left of its ramp in proportion to x, by up to ~10.5 px at the right edge. This is in the original code and the paper's model was trained through it. If you are reproducing the paper, mirror train.py; if you are training something new, scale x by 352/683 instead.

Usage

from datasets import load_dataset

ds = load_dataset("projectsidewalk/rampnet-crop-model-dataset-round1", split="train")
row = ds[0]
print(row["crop_id"], row["image"].size, row["keypoints"])

Provenance

FieldValue
Pipeline codehttps://github.com/ProjectSidewalk/RampNet @ e8b8b28
Exported2026-08-05 by scripts/export_crop_dataset.py
Replication ledgerdocs/replication.md

Crops derive from Project Sidewalk labels over Google Street View panoramas; the contributing cities are listed in the training-data contamination registry in docs/data_provenance.md, which you should read before evaluating any RampNet-derived model in those cities.

Citation

@inproceedings{omeara2025rampnet,
  author    = {John S. O'Meara and Jared Hwang and Zeyu Wang and Michael Saugstad and Jon E. Froehlich},
  title     = {{RampNet: A Two-Stage Pipeline for Bootstrapping Curb Ramp Detection in Streetscape Images from Open Government Metadata}},
  booktitle = {{ICCV'25 Workshop on Vision Foundation Models and Generative AI for Accessibility: Challenges and Opportunities (ICCV 2025 Workshop)}},
  year      = {2025},
  doi       = {https://doi.org/10.48550/arXiv.2508.09415},
}
accessibility
curb-ramp
project-sidewalk
streetscape

projectsidewalk/rampnet-crop-model-dataset-round1

Dataset

RampNet Crop-Model Dataset — Round 1 (Project Sidewalk crops)

0

3 commits

1 linked in READMEs

updated Aug 6, 2026

See the code

README

RampNet Crop-Model Dataset — Round 1 (Project Sidewalk crops)

The training data behind round 1 of the RampNet Stage 1 crop model — 27,704 crops, 13.37 GB — from RampNet: A Two-Stage Pipeline for Bootstrapping Curb Ramp Detection in Streetscape Images from Open Government Metadata (O'Meara et al., ICCV'25 CV4A11y workshop, arXiv:2508.09415).

The crop model is what turns a government curb ramp GPS coordinate into a pixel keypoint on a panorama; every label in rampnet-dataset was placed by it. It is trained in two rounds:

rounddatawhere
1Project Sidewalk cropsthis repo
2manually labeled cropsrampnet-crop-model-dataset-round2

The resulting checkpoints are at rampnet-crop-model.

Why this needed publishing

It cannot be regenerated. stage_one/crop_model/ps_model/data/download_data.py fetches from the live Project Sidewalk servers with no snapshot pinning, and those databases keep growing — so re-running it today builds a different training set, not this one. The same is true of the train/val/test partition: splititup.sh shuffles with shuf and no seed, so the 70/15/15 split here is not reproducible either. Both are reasons to ship the artifact rather than instructions.

How these crops were made

Every step below is download_data.py; the constants live in that script, not in a config.

  1. Source labels. Crowdsourced curb ramp labels fetched live from 12 Project Sidewalk deployments (Seattle, Chicago, Pittsburgh, St. Louis, Columbus, Knoxville, Newberg, Oradell, Teaneck, Cliffside Park, Mendota, Blackhawk Hills), keeping only CurbRamp labels whose crowd validation satisfies Agree − Disagree ≥ 2.
  2. Panorama fetch. Each label's GSV panorama is downloaded as zoom-4 tiles, assembled, trimmed, and resized to an 8192×4096 equirectangular.
  3. Projection. The label's panorama x becomes a yaw angle, snapped to the nearest 30° (so there are 12 possible camera headings per panorama). A perspective view is rendered at FOV 90°, pitch −30° (looking down at the street corner), 2048×2048 — and only the central horizontal third is kept: columns int(2048/3) to int(2048·2/3), which is where the 683×2048 shape comes from (≈37° effective horizontal field of view).
  4. Keypoints. The anchor label plus every other validated label on the same panorama is projected into that view with the matching point transform; neighbours landing inside the strip are appended to the filename. Each keypoint is the projection of the label's stored Project Sidewalk panorama coordinate — no re-annotation happened at crop time. The 30° yaw snap keeps the anchor within ~±15° of the view axis, which guarantees it lands inside the strip: that is why no crop in this set is empty.
  5. Naming and split. Filenames get a fresh random 8-character uid (see crop_uid below) plus the point list; splititup.sh then makes the unseeded 70/15/15 partition.

Contents

columnmeaning
crop_idthe original filename stem
crop_uidthe opaque 8-character token the filename starts with — not a panorama id
imagethe crop, stored as the exact source bytes — 683×2048 JPEG, not re-encoded
keypointslist of {x, y} curb ramp locations
n_keypointshow many
width, heightpixel dimensions as stored
sha256hash of the exact bytes

27,704 crops carry 35,757 keypoints between them. There are no negative crops in this round: every crop carries at least one keypoint, so a model trained on this set alone never sees an empty example.

keypoints in a cropcrops
121,751
24,629
3840
4293
5106
677
74
94

The keypoints were hiding in the filenames

In the original dataset the labels are encoded in the filename and parsed at load time: 007mz25c_-_118_596_-_478_611.jpg carries keypoints (118, 596) and (478, 611). Here they are a real column.

crop_uid is not a panorama id, and the panorama is not recoverable

The leading token looks like an id you could join on. It is not one. download_data.py:277 builds each filename with random.choices(alphabet, k=8), so the token is freshly random per crop and the Project Sidewalk panorama it was cut from is not stored anywhere in this artifact. Every one of the 27,704 crops has a distinct token, so nothing collided — but that is a property of this draw, not a guarantee. If you need crop → panorama provenance, it is not here.

The x axis carries a 3.1% label/image mismatch

Coordinates are stored verbatim, in the pixel space of the stored crop (683×2048), and are deliberately not normalised — because normalising would force a choice about the following, and that choice belongs to you.

train.py resizes every crop with transforms.Resize((1024, 352)) and scales both keypoint axes by 0.5:

axisimage scalekeypoint scaleagree?
y2048 → 1024 = 0.50.5yes
x683 → 352 = 0.51540.5no — off by 3.1%

So y is consistent and x is under-scaled: in the resized 352-px-wide crop a label drifts left of its ramp in proportion to x, by up to ~10.5 px at the right edge. This is in the original code and the paper's model was trained through it. If you are reproducing the paper, mirror train.py; if you are training something new, scale x by 352/683 instead.

Usage

from datasets import load_dataset

ds = load_dataset("projectsidewalk/rampnet-crop-model-dataset-round1", split="train")
row = ds[0]
print(row["crop_id"], row["image"].size, row["keypoints"])

Provenance

FieldValue
Pipeline codehttps://github.com/ProjectSidewalk/RampNet @ e8b8b28
Exported2026-08-05 by scripts/export_crop_dataset.py
Replication ledgerdocs/replication.md

Crops derive from Project Sidewalk labels over Google Street View panoramas; the contributing cities are listed in the training-data contamination registry in docs/data_provenance.md, which you should read before evaluating any RampNet-derived model in those cities.

Citation

@inproceedings{omeara2025rampnet,
  author    = {John S. O'Meara and Jared Hwang and Zeyu Wang and Michael Saugstad and Jon E. Froehlich},
  title     = {{RampNet: A Two-Stage Pipeline for Bootstrapping Curb Ramp Detection in Streetscape Images from Open Government Metadata}},
  booktitle = {{ICCV'25 Workshop on Vision Foundation Models and Generative AI for Accessibility: Challenges and Opportunities (ICCV 2025 Workshop)}},
  year      = {2025},
  doi       = {https://doi.org/10.48550/arXiv.2508.09415},
}
accessibility
curb-ramp
project-sidewalk
streetscape