CoolFace
Datasetpublic

vanshi-ka/bdappv

BDAPPV — Aerial Images of Rooftop Photovoltaic Installations BDAPPV is a dataset of aerial images of rooftop PV installations in France and Belgium, with segmentation masks and installation metadata. Images are provided by two aerial imagery providers (Google and IGN), making it suitable for both segmentation/classification benchmarks and distribution shift evaluation across imagery sources. Paper: Kasmi et al., Scientific Data, 2023 — arXiv:2209.03726 Dataset… See the full description on the dataset page: https://huggingface.co/datasets/vanshi-ka/bdappv.

sourceHugging Facecc-by-4.0updated 2mo agoView on Hugging Face
0likes126downloads
Dataset Card

BDAPPV — Aerial Images of Rooftop Photovoltaic Installations

BDAPPV is a dataset of aerial images of rooftop PV installations in France and Belgium, with segmentation masks and installation metadata. Images are provided by two aerial imagery providers (Google and IGN), making it suitable for both segmentation/classification benchmarks and distribution shift evaluation across imagery sources.

Paper: Kasmi et al., Scientific Data, 2023arXiv:2209.03726


Dataset overview

ProviderImagesPositifs (masks)NégatifsNote
Google28,40813,30315,105399 images excluded (no metadata entry)
IGN17,3257,6859,640
  • Images are 400×400 px PNG files.
  • Google images are a superset: every IGN installation also has a Google image.
  • Masks are binary PNGs (same resolution as images).

Data structure

bdappv/
├── google/
│   ├── img/    # 28,408 images (28,807 raw − 399 excluded)
│   └── mask/   # 13,303 segmentation masks
├── ign/
│   ├── img/    # 17,325 images
│   └── mask/   #  7,685 segmentation masks
├── annotations.csv   # manifest: one row per (installation × provider)
├── metadata.csv      # installation-level metadata
└── README.md

Loading the dataset

python
from datasets import load_dataset

# Google imagery (default)
ds = load_dataset("gabrielkasmi/bdappv", "google")

# IGN imagery
ds = load_dataset("gabrielkasmi/bdappv", "ign")

Each example contains:

python
{
    "identifiant": "OSIBG1RDEDJ",   # installation ID
    "image":       <PIL Image>,      # 400×400 aerial image
    "mask":        <PIL Image>,      # segmentation mask (None if has_mask=False)
    "has_mask":    True,             # False = negative sample (no panel)
    "split":       "train",          # train / val / test
    "surface":     22.0,             # panel surface (m²)
    "azimuth":     -20.0,            # panel azimuth (degrees)
    "tilt":        20.0,             # panel tilt (degrees)
    "kWp":         3010.0,           # peak power (Wp)
    "departement": 31,               # French department code
    "city":        "Castanet-Tolosan",
    "dateInstalled": "2007-09-01",
    ...
}

Recommended usage patterns

Segmentation (positives only)

python
ds = load_dataset("gabrielkasmi/bdappv", "google")
train_seg = ds["train"].filter(lambda x: x["has_mask"])
# 13,303 images with masks across all splits

Binary classification (panel / no panel)

python
# Both providers have validated negatives
ds_google = load_dataset("gabrielkasmi/bdappv", "google")  # 13,303 pos / 15,105 neg
ds_ign    = load_dataset("gabrielkasmi/bdappv", "ign")      #  7,685 pos /  9,640 neg
# has_mask is the binary label (True = panel present)

Distribution shift benchmark (cross-provider)

The intended protocol for evaluating robustness to imagery distribution shift:

python
train = load_dataset("gabrielkasmi/bdappv", "google", split="train")
test  = load_dataset("gabrielkasmi/bdappv", "ign",    split="test")
# Train on Google, evaluate on IGN — same installations, different sensors

Note: pooling both providers for training is not recommended as a default setup. Google and IGN images of the same installation share the same ground truth object; pooling them amounts to domain augmentation rather than independent data, and conflates the distribution shift signal. If you want to pool, build a custom dataloader merging both configs.


Train / val / test split

Split is based on spatial holdout by French department to prevent geographic leakage between splits. All Belgian and small-department installations are assigned to train.

SplitInstallationsDepartments
train20,707 (73%)all others
val3,817 (13%)3, 9, 11, 23, 44, 47, 52, 54, 59, 66, 72, 82, 88, 92
test3,884 (14%)2, 4, 6, 15, 16, 32, 38, 42, 51, 64, 67, 85, 91

The split is fixed and deterministic (seed=42). Do not re-split to ensure comparability with published results.


Licenses

This dataset combines components under different licenses:

ComponentLicense
Segmentation masks & annotationsCC-BY 4.0
Installation metadataCC-BY 4.0
Google aerial imagesGoogle Earth Engine ToS — and underlying third-party imagery licensing (restrictions on redistribution apply)
IGN aerial imagesEtalab Open License 2.0 — free incl. commercial use

Important: the Google imagery restricts commercial use. For commercial applications, use the IGN configuration only (load_dataset("gabrielkasmi/bdappv", "ign")).


Citation

bibtex
@article{kasmi2023bdappv,
  title     = {A crowdsourced dataset of aerial images with annotated solar
               photovoltaic arrays and installation metadata},
  author    = {Kasmi, Gabriel and Saint-Drenan, Yves-Marie and Trebosc, David
               and Jolivet, Rapha{\"e}l and Leloux, Jonathan and Sarr, Babacar
               and Dubus, Laurent},
  journal   = {Scientific Data},
  volume    = {10},
  number    = {1},
  pages     = {59},
  year      = {2023},
  publisher = {Nature Publishing Group},
  doi       = {10.1038/s41597-023-01951-4}
}