{"id":18573552,"url":"https://github.com/prs-eth/popcorn","last_synced_at":"2025-04-10T07:32:13.765Z","repository":{"id":228208274,"uuid":"773310992","full_name":"prs-eth/Popcorn","owner":"prs-eth","description":"🍿POPCORN: High-resolution Population Maps Derived from Sentinel-1 and Sentinel-2 🌍🛰️","archived":false,"fork":false,"pushed_at":"2024-07-31T10:04:07.000Z","size":11013,"stargazers_count":13,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-08-01T11:16:57.590Z","etag":null,"topics":["deep-learning","population-mapping","remote-sensing","sentinel-1","sentinel-2","super-resolution","weakly-supervised-learning"],"latest_commit_sha":null,"homepage":"https://popcorn-population.github.io/","language":"Jupyter Notebook","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/prs-eth.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-03-17T10:23:00.000Z","updated_at":"2024-08-01T07:26:35.000Z","dependencies_parsed_at":"2024-04-08T09:31:41.320Z","dependency_job_id":"57cccad1-7aa1-485c-b4e6-41ad32c583fc","html_url":"https://github.com/prs-eth/Popcorn","commit_stats":null,"previous_names":["prs-eth/popcorn"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prs-eth%2FPopcorn","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prs-eth%2FPopcorn/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prs-eth%2FPopcorn/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prs-eth%2FPopcorn/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/prs-eth","download_url":"https://codeload.github.com/prs-eth/Popcorn/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223430255,"owners_count":17143625,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["deep-learning","population-mapping","remote-sensing","sentinel-1","sentinel-2","super-resolution","weakly-supervised-learning"],"created_at":"2024-11-06T23:10:49.839Z","updated_at":"2025-04-10T07:32:13.747Z","avatar_url":"https://github.com/prs-eth.png","language":"Jupyter Notebook","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"imgs/POPCORN_logo_wide.png\" alt=\"POPCORN LOGO\" width=\"600\"/\u003e\n\u003c/p\u003e\n\n\n\u003ch1 align=\"center\"\u003e\n  🍿POPCORN: High-resolution Population Maps Derived from Sentinel-1 and Sentinel-2 🌍🛰️\n\u003c/h1\u003e\n\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://nandometzger.github.io/\"\u003e\u003cstrong\u003eNando Metzger\u003c/strong\u003e\u003c/a\u003e\u003csup\u003e🏦📧\u003c/sup\u003e,\n    \u003ca href=\"https://rcdaudt.github.io/\"\u003e\u003cstrong\u003eRodrigo Caye Daudt\u003c/strong\u003e\u003c/a\u003e\u003csup\u003e🏦\u003c/sup\u003e,\n    \u003ca href=\"https://people.epfl.ch/devis.tuia\"\u003e\u003cstrong\u003eDevis Tuia\u003c/strong\u003e\u003c/a\u003e\u003csup\u003e🍇\u003c/sup\u003e,\n    \u003ca href=\"https://igp.ethz.ch/personen/person-detail.html?persid=143986\"\u003e\u003cstrong\u003eKonrad Schindler\u003c/strong\u003e\u003c/a\u003e\u003csup\u003e🏦\u003c/sup\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003csup\u003e🏦\u003c/sup\u003e Photogrammetry and Remote Sensing, ETH Zürich\u003cbr\u003e\n  \u003csup\u003e🍇\u003c/sup\u003e Environmental Computation Science and Earth Observation Laboratory, EPFL Sion\u003cbr\u003e\n  \u003csup\u003e📧\u003c/sup\u003e Corresponding Author: nando.metzger@geod.baug.ethz.ch\n\u003c/p\u003e\n\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://popcorn-population.github.io/\"\u003e\u003cimg src=\"imgs/badge-website.svg\" alt=\"Website\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://arxiv.org/abs/2311.14006\"\u003e\u003cimg src=\"https://img.shields.io/badge/arXiv-PDF-b31b1b\" alt=\"Paper\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://ee-nandometzger.projects.earthengine.app/view/popcornv1-rwa\"\u003e\u003cimg src=\"https://img.shields.io/badge/%20Earth%20Engine-Demo-blue\" alt=\"EE_Demo\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://code.earthengine.google.com/f90c3d3a77ec4dcfeb645457a87ddf48\"\u003e\u003cimg src=\"https://img.shields.io/badge/%20Earth%20Engine-Data-blue\" alt=\"EE_Code\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://drive.google.com/drive/folders/1BEIrYL-n1lLQ_vvna5r0HRESpLaQMOfT?usp=drive_link\"\u003e\u003cimg src=\"https://img.shields.io/badge/%20GIS%20friendly%20.tif-Data-yellow\" alt=\"EE_Code\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/jvargasmu/population_estimation\"\u003e\u003cimg src=\"https://img.shields.io/badge/%20Previous%20Model-POMELO-green\" alt=\"EE_Code\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\n\u003e #### 💡 **TL;DR**\n\u003e **POPCORN** is a lightweight population mapping method using free satellite images and minimal data, surpassing existing accuracy and providing interpretable maps for mapping populations in data-scarce regions.\n\n## News 📰\n\n- 31st July 2024: We uploaded downloading scripts for single frames for the GEE and also the Sentinel-Hub platform. Moreover, we also included the inference-only scripts. \n- 14th May 2024: Predictions for Switzerland (`che`), Rwanda (`rwa`), and Puerto Rico (`pricp2`) are now downloadable in `.tif` format. \u003ca href=\"https://drive.google.com/drive/folders/1BEIrYL-n1lLQ_vvna5r0HRESpLaQMOfT?usp=drive_link\" target=\"_blank\"\u003eDownload the data here\u003c/a\u003e\n- 12th May 2024: We updated the code base with our sparse head implementation. All experiments can now be run with \u003c24GB GPU Memory. See [#4](https://github.com/prs-eth/Popcorn/pull/4).\n- 8th May 2024: We published the training code. \u003ca href=\"https://github.com/prs-eth/popcorn/\" target=\"_blank\"\u003eView Code on GitHub\u003c/a\u003e\n- 20th March 2024: We published the evaluation code and the pretrained models. \u003ca href=\"https://github.com/prs-eth/popcorn/\" target=\"_blank\"\u003eView Code on GitHub\u003c/a\u003e\n- 17th March 2024: Website is live. \u003ca href=\"https://popcorn-population.github.io/\" target=\"_blank\"\u003eVisit Website\u003c/a\u003e\n\n\n### Abstract 🔍 \nDetailed population maps play an important role in diverse fields ranging from humanitarian action to urban planning. \nGenerating such maps in a timely and scalable manner presents a challenge, especially in data-scarce regions.\nTo address it we have developed POPCORN, a population mapping method whose only inputs are free, globally available satellite images from Sentinel-1 and Sentinel-2; and a small number of aggregate population counts over coarse census districts for calibration.\nDespite the minimal data requirements our approach surpasses the mapping accuracy of existing schemes, including several that rely on building footprints derived from high-resolution imagery.\nE.g., we were able to produce population maps for Rwanda with 100m GSD based on less than 400 regional census counts. \nIn Kigali, those maps reach an R^2 score of 66% w.r.t. a ground truth reference map, with an average error of only 10 inhabitants/ha.\nConveniently, POPCORN retrieves explicit maps of built-up areas and of local building occupancy rates, making the mapping process interpretable and offering additional insights, for instance about the distribution of built-up, but unpopulated areas (e.g., industrial warehouses).\nMoreover, we find that, once trained, the model can be applied repeatedly to track population changes; and that it can be transferred to geographically similar regions with only a moderate loss in performance (e.g., from Uganda to Rwanda).\nWith our work we aim to democratize access to up-to-date and high-resolution population maps, recognizing that some regions faced with particularly strong population dynamics may lack the resources for costly micro-census campaigns.\n\nThe population map of Rwanda is available on Google Earth Engine:\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"imgs/popcorn_code2.png\" alt=\"EE DEMO\" width=\"500\"/\u003e\n\u003c/p\u003e\n\n```\nvar popDensity = ee.Image(\"projects/ee-nandometzger/assets/POPCORNv3\");\n```\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"imgs/ee_demo.gif\" alt=\"EE DEMO\" width=\"600\"/\u003e\n\u003c/p\u003e\n\n\u003c!-- \n![Bunia Time Series](imgs/series_bunia.jpg)\n--\u003e\n\n## Methodology 🧠🛰️💻\n\nThe core of our method is a neural network model, termed POPCORN. That model has two components: (1) a pre-trained, frozen built-up area extractor; and (2) a building occupancy module that we train through weak supervision with coarse census counts, as illustrated in the Figure below.\n\nThe model operates at the full Sentinel-1/-2 resolution, i.e., its output has a nominal spatial resolution of 10m. However, for the final product and evaluation, we recommend aggregating the raw output to a 1ha (100x100m) grid, as done for the evaluation of the paper.\n\n![Graphical Abstract](imgs/graphical_abstract_v17.jpg)\n\n## Setup 🔧💾\n\n### Environment 🐍\n\n#### Model training and testing\n\nInstructions on how to install the project or library (tested with Python 3.10.12)\n\nSet up the base environment like this:\n```bash\npython -m venv PopMapEnv\nsource PopMapEnv/bin/activate\npip install torch==2.5.0 torchvision==0.20.0 --index-url https://download.pytorch.org/whl/cu124\npip install -r requirements.txt\n```\nCode was tested on Ubuntu 22.04 LTS, 64GB RAM, NVIDIA GeForce RTX 3090 Ti.\n\n#### Dataset reproducability\n\nIf you plan to use the preprocessing tools in this reposiotry, you also need additional packages:\n\n```bash\npip install -r requirements.txt -r requirements+.txt\n```\n\n Moreover, you need to compile GDAL. An easy way to install GDAL without sudo access is as follows:\n - download the [gdal-3.4.1 binary](https://gdal.org/download.html), and extract it.\n - install GDAL using these commands (this might take some time):\n```bash\n./autogen.sh\n./configure\nmake\n```\n\n### Data 🌐🗂️\n\nThe code repository contains all the necessary functionalities to reproduce the dataset from the raw data and Google Earth Engine. For the user's convenience, we host necessary preprocessed datasets [here](https://drive.google.com/drive/folders/1jExHgmVrIznKRrG2Mc6_d1-6HfyJJUhk?usp=sharing). Download and place the data into the following folder structure for Switzerland (`che`), Rwanda (`rwa`), and Puerto Rico (`pricp2`), and make sure to append your data root path in the variables at [constants.py](https://github.com/prs-eth/Popcorn/blob/main/utils/constants.py).\n\n```\nPopMapData/\n├── raw/\n│   └── ... (only needed to recompute the dataset processing)\n├── processed/\n│   ├── che\n│   │   ├──census_fine.csv\n│   │   ├──boundaries_fine.tif\n│   │   ├──census_coarse4.csv\n│   │   ├──boundaries_coarse4.tif\n│   ├── rwa\n│   │   ├──census_coarse.csv\n│   │   ├──boundaries_coarse.tif\n│   │   ├──census_kigali100.csv\n│   │   ├──boundaries_kigali100.tif\n│   │   └── ...\n│   └── pricp2\n│       └── ...\n└── merged/\n    └── EE/\n        ├── che\n        │   ├── S1spring\n        │   │   └──rwa_S1spring.tif\n        │   ├── S1summer\n        │   │   └──rwa_S1summer.tif\n        │   ├── S1autumn\n        │   │   └──rwa_S1autumn.tif\n        │   ├── S1winter\n        │   │   └──rwa_S1winter.tif\n        │   ├── S2Aspring\n        │   │   └──rwa_S2Aspring.tif\n        │   ├── S2Asummer\n        │   │   └──rwa_S2Asummer.tif\n        │   └── ...\n        ├── rwa\n        │   └── ...\n        └── pricp2\n            └── ...\n```\n\n## Testing 🧪🗺️\n\n### Checkpoints 💾\n\nCheckpoints can be downloaded from [here](https://drive.google.com/drive/folders/1rOHSZmAQLzM1HwTv3PooqApggTq_rCr0?usp=sharing).\n\n### Inference 🚀📊⚖️ \n\nMake sure to add you datapath in the `utils/constants.py` file. You can now use the `run_eval.py` script to generate maps and evaluate them subsequently using\n```\npython run_eval.py -occmodel -senbuilds -S2 -NIR -S1 -treg \u003cinference dataset name\u003e --fourseasons \\\n  --resume \\\n    /path/to/model1/last_model.pth \\\n    /path/to/model2/last_model.pth \\\n    ....\n```\nThe outputs will be written into the folder of the first model. `/path/to/model1/last_model.pth` in the case above\n\n## Training 🏋️‍♂️ \n\n\u003e Note: The training script loads large chunks of data per sample. We recommend to use SSDs for data storing to avoid bottlenecks. \n\nTrain Switzerland (Estimated training time: ~15h):\n```\npython run_train.py -S2 -NIR -S1 -treg che -tregtrain che -occmodel -wd 0.0000005 -senbuilds -pret --biasinit 0.2267\n```\n\nTrain Rwanda projected census 2020 (Estimated training time: ~8h):\n```\npython run_train.py -S2 -NIR -S1 -treg rwa -tregtrain rwa -occmodel -wd 0.00001 -senbuilds -pret --biasinit 0.9407\n```\n\nTrain Puerto Rico (Estimated training time: ~6h):\n```\npython run_train.py -S2 -NIR -S1 -treg pricp2 -tregtrain pricp2 -occmodel -wd 0.0000005 -senbuilds -pret --biasinit 0.4119\n```\n\nUganda:\n```\npython run_train.py -S2 -NIR -S1 -treg uga -tregtrain rwa2022 -occmodel -wd 0.00001 -senbuilds -pret --biasinit 0.9407\n```\n\nFor the results in the paper, we trained the Bag-of-POPCORN with parameter settings `--seed {1600,1601,1602,1603,1604}`, default is `1600`.\n\n\n## Recompute the dataset 🖥️\n\nTo ensure full reproducibility and additional expandability of our workflow. We provide the full data pipeline to recompute the input images:\n\n### 1. Connect to Google Earth Engine \n\nMake sure you have the [gcloud](https://cloud.google.com/sdk/docs/install#linux) application installed. You need a Google Earth Engine account for this.\n\n#### Local Machine\n\nIf you are on a local machine, you can log in via this command, which will prompt the login page on your browser.\n```\ngcloud auth application-default login\n```\n\n#### Remote Machine (SSH)\n\nIf you are on a remote machine, make sure gcloud is installed on the local as well as the remote device. Connect via ssh to you remote machine and run the following command on your *remote* terminal: \n```\ngcloud auth application-default login --no-browser\n```\nThis will generate another gcloud command like `gcloud auth application-default login --remote-bootstrap=\"....\"`. Copy this command and paste it into your *local* terminal.\nAccept that you are bootstrapping glcoud to a trusted machine, and the Earth Engine login window in your browser should be prompted. After successful browser authentification, your local terminal should provide an output `https://localhost:8085/...`. Copy and paste this line into your remote terminal. \n\n### 2. Download raw data\n```\npython utils/01_download_gee_country.py 28.782241 -2.903950 30.961654 -0.994897 rwa\npython utils/01_download_gee_country.py 5.855713 45.759859 10.656738 47.864774 che\npython utils/01_download_gee_country.py -67.282031 17.874492 -65.205615 18.522873 pricp2\npython utils/01_download_gee_country.py 29.492798 -1.554375 35.095825 4.291636 uga\n```\nThe resulting files will appear in your google drive.\n\n\n### 3. Merging Google Earth Engine outputs\n\nFor large regions, GEE will return individual tiles of the scenes. You can merge them together with the `utils/03_merge_tiffs.py` script. We recommend placing the tiles in the `raw/EE/\u003cregion\u003e/\u003cmodality\u003e` folders, where the modality is `S1spring` or `S2Awinter` for example. You can then execute the following commands to perform the merging:\n\n```\npython utils/03_merge_tiffs.py \u003cpath to data\u003e/PopMapData/raw/EE/rwa \u003cpath to data\u003e/PopMapData/merged/EE/rwa \npython utils/03_merge_tiffs.py \u003cpath to data\u003e/PopMapData/raw/EE/che \u003cpath to data\u003e/PopMapData/merged/EE/che \npython utils/03_merge_tiffs.py \u003cpath to data\u003e/PopMapData/raw/EE/pricp2 \u003cpath to data\u003e/PopMapData/merged/EE/pricp2 \npython utils/03_merge_tiffs.py \u003cpath to data\u003e/PopMapData/raw/EE/uga \u003cpath to data\u003e/PopMapData/merged/EE/uga \n```\n\n\u003e Note: This process applies a lossless compression, but the outputs can still be quite large. There is a automatic functionality in the dataloader to create virtual files, in case merged files cannot be created here. \n\n### 4. Census files preprocessing\n\n#### Rwanda\n Download the additional data:\n 1. [Coarse Census Boundaries](https://data.humdata.org/dataset/cod-ab-rwa)\n 2. [Finegrained Kigali Census Data](https://zenodo.org/record/7712047)\n 3. [WorldPop Census data from their FTP server](https://sdi.worldpop.org/wpdata) path: `/GIS/Population/Global_2000_2020/CensusTables/rwa_population_2000_2020.csv`\n 4. [WorldPop Subnational boarders from their FTP server](https://sdi.worldpop.org/wpdata) `/GIS/Mastergrid/Global_2000_2020/RWA/Subnational/Shapefile/`\n \nWe recommend tools like Filezilla for easy exploration of the WorldPop FTP server in case their server paths change in the future.\n\n```bash\npython utils/02_preprocess_rwa_shapefile.py \\\n  --hd_regions_path /\u003cpath to data\u003e/rwa_adm_2006_nisr_wgs1984_20181002_shp/rwa_adm3_2006_NISR_WGS1984_20181002.shp \\\n  --wp_regions_path /\u003cpath to data\u003e/RWA/Subnational/Shapefile/ \\\n  --census_data_path \u003cpath to data\u003e/GIS/Population/Global_2000_2020/CensusTables/rwa_population_2000_2020.csv \\\n  --kigali_census_data_path \u003cpath to data\u003e/pop_growth_dataset/ancillary_data/population_grid_level_2020_kigali.tiff \\\n  --output_path /\u003cpath to data\u003e/PopMapData/processed/rwa/ \\\n  --target_col P_2020 \\\n  --template_file /\u003cpath to data\u003e/PopMapData/merged/EE/rwa2022/S2Aspring/rwa2022_S2Aspring.tif \n```\n\n\n## Citation 🎓\n\n```\n@article{metzger2023high,\n  title={High-resolution Population Maps Derived from Sentinel-1 and Sentinel-2},\n  author={Metzger, Nando and Daudt, Rodrigo Caye and Tuia, Devis and Schindler, Konrad},\n  journal={arXiv preprint arXiv:2311.14006},\n  year={2023} \n}\n```\n\n## Fun fact\n\n - \"POPCORN\" stands for POPulation from COaRrse census Numbers🍿. \n - POPCORN is the successor of [POMELO](https://www.nature.com/articles/s41598-022-24495-w)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprs-eth%2Fpopcorn","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprs-eth%2Fpopcorn","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprs-eth%2Fpopcorn/lists"}