{"id":618,"name":"Sentinel-Tree-Cover","description":"This project maps tree extent at the ten-meter scale using open source artificial intelligence and satellite imagery.","url":"https://github.com/wri/sentinel-tree-cover","last_synced_at":"2026-04-08T02:30:36.796Z","repository":{"id":38296967,"uuid":"238256084","full_name":"wri/sentinel-tree-cover","owner":"wri","description":"Image segmentations of trees outside forest","archived":false,"fork":false,"pushed_at":"2025-12-08T16:13:23.000Z","size":1586786,"stargazers_count":173,"open_issues_count":5,"forks_count":40,"subscribers_count":12,"default_branch":"master","last_synced_at":"2026-01-19T17:35:06.355Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Jupyter Notebook","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wri.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2020-02-04T16:49:33.000Z","updated_at":"2025-12-26T07:11:34.000Z","dependencies_parsed_at":"2025-04-17T09:45:36.881Z","dependency_job_id":null,"html_url":"https://github.com/wri/sentinel-tree-cover","commit_stats":{"total_commits":241,"total_committers":5,"mean_commits":48.2,"dds":0.4813278008298755,"last_synced_commit":"9b9f11ecf1ca6cc0df990a667e2c28e286360ce4"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/wri/sentinel-tree-cover","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wri%2Fsentinel-tree-cover","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wri%2Fsentinel-tree-cover/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wri%2Fsentinel-tree-cover/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wri%2Fsentinel-tree-cover/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wri","download_url":"https://codeload.github.com/wri/sentinel-tree-cover/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wri%2Fsentinel-tree-cover/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29094657,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-04T19:16:55.479Z","status":"ssl_error","status_checked_at":"2026-02-04T19:16:52.508Z","response_time":62,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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"}},"owner":{"login":"wri","name":"World Resources Institute","uuid":"4615146","kind":"organization","description":"","email":"datalab@wri.org","website":"https://wri.org","location":"Washington, DC","twitter":null,"company":null,"icon_url":"https://avatars.githubusercontent.com/u/4615146?v=4","repositories_count":207,"last_synced_at":"2024-04-14T16:16:20.039Z","metadata":{"has_sponsors_listing":false},"html_url":"https://github.com/wri","funding_links":[],"total_stars":1155,"followers":97,"following":0,"created_at":"2022-11-03T00:18:19.167Z","updated_at":"2024-04-14T16:17:11.365Z","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wri","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wri/repositories"},"packages":[],"commits":{"id":1254295,"full_name":"wri/sentinel-tree-cover","default_branch":"master","total_commits":244,"total_committers":5,"total_bot_commits":0,"total_bot_committers":0,"mean_commits":48.8,"dds":0.4877049180327869,"past_year_total_commits":3,"past_year_total_committers":1,"past_year_total_bot_commits":0,"past_year_total_bot_committers":0,"past_year_mean_commits":3.0,"past_year_dds":0.0,"last_synced_at":"2026-02-01T19:21:41.961Z","last_synced_commit":"437b2a2a07ba833ea1267fa4bbed71fc75a02464","created_at":"2023-03-27T11:31:55.747Z","updated_at":"2025-12-15T10:10:29.708Z","committers":[{"name":"John Brandt","email":"=","login":null,"count":125},{"name":"John Brandt","email":"32107148+JohnMBrandt","login":"JohnMBrandt","count":100},{"name":"John Brandt","email":"john.brandt@wri.org","login":null,"count":11},{"name":"Jessica Ertel","email":"34012683+jessicarose00","login":"jessicarose00","count":7},{"name":"Justine Spore","email":"77505154+justinespore","login":"justinespore","count":1}],"past_year_committers":[{"name":"John Brandt","email":"john.brandt@wri.org","login":null,"count":3}],"commits_url":"https://commits.ecosyste.ms/api/v1/hosts/GitHub/repositories/wri%2Fsentinel-tree-cover/commits","host":{"name":"GitHub","url":"https://github.com","kind":"github","last_synced_at":"2026-02-04T00:00:11.828Z","repositories_count":6166658,"commits_count":929023352,"contributors_count":36096083,"owners_count":1139606,"icon_url":"https://github.com/github.png","host_url":"https://commits.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://commits.ecosyste.ms/api/v1/hosts/GitHub/repositories"}},"issues_stats":{"full_name":"wri/sentinel-tree-cover","html_url":"https://github.com/wri/sentinel-tree-cover","last_synced_at":"2025-08-31T11:11:45.139Z","status":"error","issues_count":21,"pull_requests_count":30,"avg_time_to_close_issue":18367518.0,"avg_time_to_close_pull_request":2511098.1785714286,"issues_closed_count":18,"pull_requests_closed_count":28,"pull_request_authors_count":4,"issue_authors_count":6,"avg_comments_per_issue":1.3333333333333333,"avg_comments_per_pull_request":0.4,"merged_pull_requests_count":18,"bot_issues_count":0,"bot_pull_requests_count":8,"past_year_issues_count":0,"past_year_pull_requests_count":1,"past_year_avg_time_to_close_issue":null,"past_year_avg_time_to_close_pull_request":10.0,"past_year_issues_closed_count":0,"past_year_pull_requests_closed_count":1,"past_year_pull_request_authors_count":1,"past_year_issue_authors_count":0,"past_year_avg_comments_per_issue":null,"past_year_avg_comments_per_pull_request":0.0,"past_year_bot_issues_count":0,"past_year_bot_pull_requests_count":0,"past_year_merged_pull_requests_count":1,"created_at":"2023-05-09T10:35:51.337Z","updated_at":"2025-09-01T23:46:15.790Z","repository_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/repositories/wri%2Fsentinel-tree-cover","issues_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/repositories/wri%2Fsentinel-tree-cover/issues","issue_labels_count":{"enhancement":12,"bug":1},"pull_request_labels_count":{"dependencies":8},"issue_author_associations_count":{"CONTRIBUTOR":15,"NONE":6},"pull_request_author_associations_count":{"CONTRIBUTOR":13,"COLLABORATOR":11,"NONE":8},"issue_authors":{"JohnMBrandt":15,"sandersson-sylvera":2,"ib-albo":1,"amiralipour":1,"theoway":1,"blossomzx":1},"pull_request_authors":{"JohnMBrandt":13,"jessicarose00":9,"dependabot[bot]":8,"justinespore":2},"host":{"name":"GitHub","url":"https://github.com","kind":"github","last_synced_at":"2026-02-04T00:00:08.688Z","repositories_count":13077419,"issues_count":35557336,"pull_requests_count":115262285,"authors_count":11144713,"icon_url":"https://github.com/github.png","host_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/repositories","owners_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/owners","authors_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors"},"past_year_issue_labels_count":{},"past_year_pull_request_labels_count":{},"past_year_issue_author_associations_count":{},"past_year_pull_request_author_associations_count":{},"past_year_issue_authors":{},"past_year_pull_request_authors":{},"maintainers":[{"login":"jessicarose00","count":9,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/jessicarose00"},{"login":"justinespore","count":2,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/justinespore"}],"active_maintainers":[]},"events":{"total":{"WatchEvent":7,"PushEvent":3,"ForkEvent":2},"last_year":{"WatchEvent":6,"PushEvent":1,"ForkEvent":2}},"keywords":[],"dependencies":[{"ecosystem":"docker","filepath":"Dockerfile","sha":null,"kind":"manifest","created_at":"2023-01-21T00:45:19.586Z","updated_at":"2023-01-21T00:45:19.586Z","repository_link":"https://github.com/wri/sentinel-tree-cover/blob/master/Dockerfile","dependencies":[{"id":7071109954,"package_name":"tensorflow/tensorflow","ecosystem":"docker","requirements":"1.15.5-gpu-py3","direct":true,"kind":"build","optional":false}]}],"score":6.7912214627261855,"created_at":"2023-09-11T11:54:35.379Z","updated_at":"2026-04-08T02:30:36.854Z","avatar_url":"https://github.com/wri.png","language":"Jupyter Notebook","category":"Biosphere","sub_category":"Forest Remote Sensing","monthly_downloads":0,"total_dependent_repos":0,"total_dependent_packages":0,"readme":"Mapping tree cover and extent with Sentinel-1 and 2\n==============================\n\n# Description\n\nThis is the GitHub repository for the Sentinel-1 and Sentinel-2 dataset Tropical Tree Cover, which is viewable on Google Earth Engine [here](https://jombrandt.users.earthengine.app/view/sentinel-tree-cover). The asset is public as of May 2023 on Google Earth Engine [here](https://code.earthengine.google.com/?asset=projects/wri-datalab/TropicalTreeCover). The dataset is published in [Remote Sensing of Environment](https://www.sciencedirect.com/science/article/pii/S0034425723001256).\n\nThe trained model and training data are in preparation for release in early 2024.\n\nThis project maps tree extent at the ten-meter scale using open source artificial intelligence and satellite imagery. The data enables accurate reporting of tree cover in urban areas, tree cover on agricultural lands, and tree cover in open canopy and dry forest ecosystems.\n\nThis repository contains the source code for the project. A full description of the methodology can be found in the [publication](https://www.sciencedirect.com/science/article/pii/S0034425723001256). The data product specifications can be accessed on the wiki page.\n*  [Background](https://github.com/wri/restoration-mapper/wiki/Product-Specifications#background)\n*  [Data Extent](https://github.com/wri/restoration-mapper/wiki/Product-Specifications#data-extent)\n*  [Methodology](https://github.com/wri/restoration-mapper/wiki/Product-Specifications#methodology)\n*  [Validation and Analysis](https://github.com/wri/restoration-mapper/wiki/Product-Specifications#validation-and-analysis) | [Jupyter Notebook](https://github.com/wri/restoration-mapper/blob/master/notebooks/analysis/validation-analysis.ipynb)\n*  [Definitions](https://github.com/wri/restoration-mapper/wiki/Product-Specifications#definitions)\n*  [Limitations](https://github.com/wri/restoration-mapper/wiki/Product-Specifications#limitations)\n\n\n\n# Citation\n\nBrandt, J., Ertel, J., Spore, J., \u0026 Stolle, F. (2023). Wall-to-wall mapping of tree extent in the tropics with Sentinel-1 and Sentinel-2. Remote Sensing of Environment, 292, 113574. doi:10.1016/j.rse.2023.113574\n\nBrandt, J. \u0026 Stolle, F. (2021) A global method to identify trees outside of closed-canopy forests with medium-resolution satellite imagery. International Journal of Remote Sensing, 42:5, 1713-1737, DOI: 10.1080/01431161.2020.1841324\n\n![img](references/screenshots/demo.gif?raw=true)\n\n# Getting started\n\nAn overview Jupyter notebook walking through the creation of the data can be found [here](https://github.com/wri/sentinel-tree-cover/blob/master/notebooks/development/Tropical%20Tree%20Cover%20technical%20introduction.ipynb)\n\nA Google Earth Engine script to export Geotiffs of the extent data by country can be found [here](https://code.earthengine.google.com/e65c9fc97fa0827012dd28b74f59d32e)\n\n# Installation\n\nUtilizing this repository to generate your own data requires:\n* Sentinel-Hub API key, see [Sentinel-hub](http://sentinel-hub.com/)\n* Amazon Web Services API key (optional) with s3 read/write privileges\n\nThe API keys should be stored as `config.yaml` in the base directory with the structure:\n\n```\nkey: \"YOUR-SENTINEL-HUB-API-KEY\"\nawskey: \"YOUR-AWS-API-KEY\"\nawssecret: \"YOUR-AWS-API-SECRET\"\n```\n\nThe code can be utilized without AWS by setting `--ul_flag False` in `download_and_predict_job.py`. By default, the pipeline will output satellite imagery and predictions in 6 x 6 km tiles to the `--s3_bucket` bucket. NOTE: The specific layer configurations for Sentinel-Hub have not yet been released but are available on request.\n\n## With Docker\n\n```\ngit clone https://github.com/wri/sentinel-tree-cover\ncd sentinel-tree-cover/\ntouch config.yaml\nvim config.yaml # insert your API keys here\ndocker build -t sentinel_tree_cover .\ndocker run -it --entrypoint /bin/bash sentinel_tree_cover:latest\ncd src\npython3 download_and_predict_job.py --country \"country\" --year year\n```\n\n## Without docker\n*  Clone repository\n*  Install dependencies `pip3 install -r requirements.txt`\n*  Install GDAL (different process for different operating systems, see https://gdal.org)\n*  Download model `python3 src/models/download_model.py`\n*  Start Jupyter notebook and navigate to `notebooks/` folder\n\n# Usage\nThe `notebooks/` folder contains ordered notebooks for downloading training and testing data and training the model, as follows:\n* 1a-download-sentinel-2: downloads monthly mosaic 10 and 20 meter bands for training / testing plots\n* 1b-download-sentinel-1: downloads monthly VV-VH db sigma Sentinel-1 imagery for training / testing plots\n* 2-data-preprocessing: Combines satellite imagery for training / testing plots with labelled data from [Collect Earth Online](collect.earth)\n* 3-feature-selection: Feature selection for remote sensing indices utilizing random forests\n* 4-model: Trains and deploys tree cover model\n\n\nThe `src/` folder contains the source code for the project, as well as the primary entrypoint for the Docker container, `download_and_predict_job_fast.py`\n\n`download_and_predict_job_fast.py` can be used as follows, with additional optional arguments listed in the file: `python3 download_and_predict_job_fast.py --country $COUNTRY --year $YEAR`\n\n# Methodology\n\n## Model\nThis model uses a U-Net architecture with the following modifications:\n*  [Convolutional GRU](https://papers.nips.cc/paper/5955-convolutional-lstm-network-a-machine-learning-approach-for-precipitation-nowcasting.pdf) encoder with group normalization to develop temporal features of monthly cloud-free mosaics\n*  Concurrent spatial and channel squeeze excitation in both the encoder and decoder (https://arxiv.org/abs/1803.02579)\n*  DropBlock and Zoneout for generalization in both the encoder and decoder\n*  Group normalization and Swish activation in both the encoder and decoder\n*  [AdaBound](https://arxiv.org/abs/1902.09843) optimizer with Stochastic Weight Averaging and Sharpness Aware Minimization\n*  Binary cross entropy and boundary loss\n*  Smoothed image predictions across moving windows with Gaussian filters\n*  A much larger input (28x28) than output (14x14) at training time, with 182x182 and 168x168 input and output size in production, respectively\n\n![img4](references/readme/model_diagram.png?raw=true)\n\n## Data\nThis project uses Sentinel 1 and Sentinel 2 imagery. Monthly composites of Sentinel 1 VV-VH imagery are fused with the nearest Sentinel 2 10- and 20-meter bands. These images are preprocessed by:\n*  Super-resolving 20m bands to 10m with DSen2\n*  Calculating cloud cover and cloud shadow masks\n*  Removing steps with \u003e30% cloud cover, and linearly interpolating to remove clouds and shadows from \u003c30% cloud cover images\n![img](references/readme/cloud_removal.gif?raw=true)\n*  Applying Whittaker smoothing (lambda = 100) to each time series for each pixel for each band to reduce noise\n![img](references/screenshots/datasmooth.png?raw=true)\n*  Calculating vegetation indices, including EVI, BI, and MSAVI2\n\nThe cloud / shadow removal and temporal mosaicing algorithm is summarized below:\n*  Select all images with \u003c30% cloud cover\n*  Select up to two images per month with \u003c30% cloud cover, closest to beginning and middle of month\n*  Select least cloudy image if max CC \u003e 15%, otherwise select the image closest to the middle of the month\n*  Linearly interpolate clouds and cloud shadows with a rolling median\n*  Smooth time series data with a rolling median\n*  Linearly interpolate image stack to a 15 day timestep\n*  Smooth time stack with Whittaker smoother\n\n# License\n\nThe code is released under the GNU General Public License v3.0.\n\n# Project Organization\n------------\n\n    ├── LICENSE\n    ├── Makefile           \u003c- Makefile with commands like `make data` or `make train`\n    ├── README.md          \u003c- The top-level README for developers using this project.\n    ├── docs               \u003c- A default Sphinx project; see sphinx-doc.org for details\n    │\n    ├── models             \u003c- Trained and serialized models, model predictions, or model summaries\n    │\n    ├── notebooks          \u003c- Jupyter notebooks\n    │   └── baseline\n    │   └── replicate-paper\n    │   └── visualization\n    │\n    ├── references         \u003c- Data dictionaries, manuals, and all other explanatory materials.\n    │\n    ├── requirements.txt   \u003c- The requirements file for reproducing the analysis environment, e.g.\n    │                         generated with `pip freeze \u003e requirements.txt`\n    │\n    ├── setup.py           \u003c- makes project pip installable (pip install -e .) so src can be imported\n    ├── src                \u003c- Source code for use in this project.\n    │   ├── __init__.py    \u003c- Makes src a Python module\n    │   │\n    │   ├── data           \u003c- Scripts to download or generate data\n    │   │   └── make_dataset.py\n    │   │\n    │   ├── features       \u003c- Scripts to turn raw data into features for modeling\n    │   │   └── build_features.py\n    │   │\n    │   ├── models         \u003c- Scripts to train models and then use trained models to make\n    │   │   │                 predictions\n    │   │   ├── predict_model.py\n    │   │   └── train_model.py\n    │   │\n    │   └── visualization  \u003c- Scripts to create exploratory and results oriented visualizations\n    │       └── visualize.py\n    │\n    └── tox.ini            \u003c- tox file with settings for running tox; see tox.testrun.org\n\n\n--------\n","funding_links":[],"readme_doi_urls":[],"works":{},"citation_counts":{},"total_citations":0,"keywords_from_contributors":["topic-modeling"],"project_url":"https://ost.ecosyste.ms/api/v1/projects/618","html_url":"https://ost.ecosyste.ms/projects/618"}