btt_cloud_mask_example
Reference cloud masks for satellite images, so you can check how well your cloud-detection model does.
The images come from Maxar Open Data: very high resolution (about 0.3–3.5 m) imagery of natural disasters, published as a free STAC catalog. The masks come from pretrained cloud models, OmniCloudMask by default.
Install
pip install btt_cloud_mask_example
This includes OmniCloudMask. Two more models are optional:
pip install "btt_cloud_mask_example[all]" # adds ukis-csmask and CloudSEN12
The first mask you make downloads OmniCloudMask's model weights (about 55 MB).
Quickstart
Images come back as a plain numpy array plus a rasterio profile (a dict with the map projection, pixel size and so on). Cloud masks come back as a plain numpy True/False array.
import btt_cloud_mask_example as bcm
import matplotlib.pyplot as plt
# 1. Find some cloudy images from a disaster event
urls = bcm.find_images("Hurricane-Ian-9-26-2022", n=3, min_cloud=20)
# 2. Load an image: reflectance values from 0 to 1, shaped (bands, height, width)
data, profile = bcm.load_image(urls[0]) # bands, in order: red, green, blue, nir
data.shape # e.g. (4, 2868, 2868)
plt.imshow(bcm.rgb(data)) # bcm.rgb makes a viewable colour picture
# 3. Make a reference cloud mask for the same image
mask = bcm.create_mask(urls[0]) # numpy bool (height, width): True = cloud
mask.mean() # e.g. 0.25: share of pixels that are cloud
plt.imshow(mask, cmap="gray")
# 4. Compare your model's prediction against the reference
my_prediction = my_model(data) # True/False, 0/1 or probabilities, shaped (height, width)
bcm.compare(my_prediction, mask)
# e.g. {'iou': 0.71, 'precision': 0.93, 'recall': 0.75, 'f1': 0.83, 'accuracy': 0.91, ...}
load_image and create_mask use the same pixel grid, so data[:, y, x] and mask[y, x] are
the same spot on the ground.
What's in a mask
mask is a numpy bool array with one value per pixel: True = cloud, False = not cloud
(clear ground, cloud shadow, or the empty edges of the image).
To also save it as a GeoTIFF that opens in QGIS (1 = cloud, 0 = not cloud), pass save_to:
mask = bcm.create_mask(url, save_to="mask.tif")
Useful options
urls = bcm.find_images(event, n=10, min_cloud=10, max_cloud=60, sensors=["WV02", "WV03"])
data, profile = bcm.load_image(url, bands=["red", "green", "blue", "nir", "rededge"]) # pick bands
data, profile = bcm.load_image(url, resolution=10) # resample to 10 m pixels (smaller, faster)
mask = bcm.create_mask(url, resolution=10) # ...and a mask on the same 10 m grid
mask = bcm.create_mask(url, model="ukis") # another model, for comparison
mask = bcm.create_mask(url, save_to="masks/one.tif")
Event names (like Hurricane-Ian-9-26-2022) are listed in the
catalog browser.
You can also pass a link copied from the browser straight into load_image or create_mask.
Bands
| Name | WorldView-2/3 (WV02, WV03) | GeoEye-1 (GE01), WorldView-4 (WV04) |
|---|---|---|
coastal, yellow, rededge, nir2 |
✓ | |
blue, green, red, nir |
✓ | ✓ |
WorldView-1 (WV01) images are black-and-white only: load them with bands=["pan"].
find_images skips them unless you ask for sensors=["WV01", ...].
Command line
cloud-detect find Hurricane-Ian-9-26-2022 --n 3 --min-cloud 20 # prints image URLs
cloud-detect mask <url> [<url> ...] --out masks # writes GeoTIFF masks
cloud-detect mask <url> --model ukis --resolution 10
The models
| Model | Install | Uses | Licence |
|---|---|---|---|
omnicloudmask (default) |
included | red, green, NIR | MIT |
ukis |
[ukis] |
blue, green, red, NIR | Apache-2.0 |
cloudsen12 |
[cloudsen12] |
NIR, red, green, blue | LGPL-3.0 code, CC-BY-NC-4.0 weights |
None of them was trained on Maxar imagery. Compared with Maxar's own cloud masks on 34 cloudy images, OmniCloudMask agreed best (cloud IoU 0.83, F1 0.90), ahead of CloudSEN12 (0.72) and ukis (0.71). Treat the masks as a strong baseline, not ground truth. Details are in docs/DETECTORS.md; data quirks are in docs/DATA.md.
Data licence
Maxar Open Data imagery is licensed CC-BY-NC-4.0 (non-commercial). This package reads it from Maxar's servers and does not redistribute it.
For developers
The friendly functions above are built on a lower-level layer you can use directly:
btt_cloud_mask_example.stac (search and download from any static STAC catalog),
.raster (reading bands, writing masks), .detectors (the model wrappers) and .pipeline.
The cloud-detect fetch and cloud-detect run commands expose the same layer.
git clone https://github.com/jeckseveg/btt_cloud_mask_example
cd btt_cloud_mask_example
pip install -e ".[all,dev]"
pytest
python -m build && twine check dist/*
Metadata
Release files for btt-cloud-mask-example 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| btt_cloud_mask_example-0.2.1.tar.gz | 22.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| btt_cloud_mask_example-0.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 46.1 kB
Release files / btt_cloud_mask_example-0.2.1.tar.gz
| Download URL | btt_cloud_mask_example-0.2.1.tar.gz |
|---|---|
| Size | 22.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5c92f568ff8d6e8f89394f2a36c6d7d67846cf514583658123bca8037d2ff573
|
|
BLAKE2b-256 checksum How to use checksums |
c3a44196e49b615f158c8a9ce409a5f67a192276377148a8e55fac99c773bc07
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.
Transparency logRelease files / btt_cloud_mask_example-0.2.1-py3-none-any.whl
| Download URL | btt_cloud_mask_example-0.2.1-py3-none-any.whl |
|---|---|
| Size | 23.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7d02643185b84546624c67c396f14ee677eb6b0495504f4f4ad5cf238afbe602
|
|
BLAKE2b-256 checksum How to use checksums |
198e8e595dc74208c3b4cade002be1ea6dfc6b0eb7e7f3646be0e2da25b23e59
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.
Transparency log