Skip to main content

SEN2SR

A Python package for enhancing the spatial resolution of Sentinel-2 satellite images up to 2.5 meters 🚀

PyPI License Black isort


GitHub: https://github.com/ESAOpenSR/sen2sr 🌐

PyPI: https://pypi.org/project/sen2sr/ 🛠️


Table of Contents

Overview

sen2sr is a Python package designed to enhance the spatial resolution of Sentinel-2 satellite images to 2.5 meters using a set of neural network models.

Model Description Run Link
Run SENSRLite A lightweight SR model optimized for running fast! Open In Colab
Run SENSR Our most accurate SR model! Open In Colab

Installation

Install the SEN2SRLite version using pip:

pip install sen2sr mlstac git+https://github.com/ESDS-Leipzig/cubo.git

For the full version, which use Mamba arquitecture, install as follows:

pip install mamba-ssm --no-build-isolation -q
pip install sen2sr mlstac git+https://github.com/ESDS-Leipzig/cubo.git

From 10m and 20m Sentinel-2 bands to 2.5m

This example demonstrates the use of the SEN2SRLite model to enhance the spatial resolution of Sentinel-2 imagery. A Sentinel-2 L2A data cube is created over a specified region and time range using the cubo library, including both 10 m and 20 m bands. The pretrained model, downloaded via mlstac, takes a single normalized sample as input and predicts a HR output. The visualization compares the original RGB composite to the super-resolved result.

import mlstac
import torch
import cubo

# Download the model
mlstac.download(
  file="https://huggingface.co/tacofoundation/sen2sr/resolve/main/SEN2SRLite/main/mlm.json",
  output_dir="model/SEN2SRLite",
)

# Load the model
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = mlstac.load("model/SEN2SRLite").compiled_model(device=device)
model = model.to(device)

# Create a Sentinel-2 L2A data cube for a specific location and date range
da = cubo.create(
    lat=39.49152740347753,
    lon=-0.4308725142800361,
    collection="sentinel-2-l2a",
    bands=["B02", "B03", "B04", "B05", "B06", "B07", "B08", "B8A", "B11", "B12"],
    start_date="2023-01-01",
    end_date="2023-12-31",
    edge_size=128,
    resolution=10
)

# Prepare the data to be used in the model, select just one sample 
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
original_s2_numpy = (da[11].compute().to_numpy() / 10_000).astype("float32")
X = torch.from_numpy(original_s2_numpy).float().to(device)

# Apply model
superX = model(X[None]).squeeze(0)

From 10m Sentinel-2 bands to 2.5m

This example demonstrates the use of the SEN2SRLite NonReference_RGBN_x4 model variant to enhance the spatial resolution of only the 10 m Sentinel-2 bands: red (B04), green (B03), blue (B02), and near-infrared (B08). A Sentinel-2 L2A data cube is created using the cubo library for a specific location and date range. The input is normalized and passed to a pretrained non-reference model optimized for RGB+NIR inputs.

import mlstac
import torch
import cubo

# Download the model
mlstac.download(
  file="https://huggingface.co/tacofoundation/sen2sr/resolve/main/SEN2SRLite/NonReference_RGBN_x4/mlm.json",
  output_dir="model/SEN2SRLite_RGBN",
)

# Create a Sentinel-2 L2A data cube for a specific location and date range
da = cubo.create(
    lat=39.49152740347753,
    lon=-0.4308725142800361,
    collection="sentinel-2-l2a",
    bands=["B04", "B03", "B02", "B08"],
    start_date="2023-01-01",
    end_date="2023-12-31",
    edge_size=128,
    resolution=10
)


# Prepare the data to be used in the model
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
original_s2_numpy = (da[11].compute().to_numpy() / 10_000).astype("float32")
X = torch.from_numpy(original_s2_numpy).float().to(device)
X = torch.nan_to_num(X, nan=0.0, posinf=0.0, neginf=0.0)

# Load the model
model = mlstac.load("model/SEN2SRLite_RGBN").compiled_model(device=device)

# Apply model
superX = model(X[None]).squeeze(0)

From 20m Sentinel-2 bands to 10m

This example demonstrates the use of the SEN2SRLite Reference_RSWIR_x2 model variant to enhance the spatial resolution of the 20 m Sentinel-2 bands: red-edge (B05, B06, B07), shortwave infrared (B11, B12), and near-infrared (B8A) to 10 m.

import mlstac
import torch
import cubo

# Download the model
mlstac.download(
  file="https://huggingface.co/tacofoundation/sen2sr/resolve/main/SEN2SRLite/Reference_RSWIR_x2/mlm.json",
  output_dir="model/SEN2SRLite_Reference_RSWIR_x2",
)

# Create a Sentinel-2 L2A data cube for a specific location and date range
da = cubo.create(
    lat=39.49152740347753,
    lon=-0.4308725142800361,
    collection="sentinel-2-l2a",
    bands=["B02", "B03", "B04", "B05", "B06", "B07", "B08", "B8A", "B11", "B12"],
    start_date="2023-01-01",
    end_date="2023-12-31",
    edge_size=128,
    resolution=10
)

# Prepare the data to be used in the model
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
original_s2_numpy = (da[11].compute().to_numpy() / 10_000).astype("float32")
X = torch.from_numpy(original_s2_numpy).float().to(device)

# Load the model
model = mlstac.load("model/SEN2SRLite_Reference_RSWIR_x2").compiled_model(device=device)
model = model.to(device)

# Apply model
superX = model(X[None]).squeeze(0)

Predict on large images

This example demonstrates the use of SEN2SRLite NonReference_RGBN_x4 for super-resolving large Sentinel-2 RGB+NIR images by chunking the input into smaller overlapping tiles. Although the model is trained to operate on fixed-size 128×128 patches, the sen2sr.predict_large utility automatically segments larger inputs into these tiles, applies the model to each tile independently, and then reconstructs the full image. An overlap margin (e.g., 32 pixels) is introduced between tiles to minimize edge artifacts and ensure continuity across tile boundaries.

import mlstac
import sen2sr
import torch
import cubo

# Create a Sentinel-2 L2A data cube for a specific location and date range
da = cubo.create(
    lat=39.49152740347753,
    lon=-0.4308725142800361,
    collection="sentinel-2-l2a",
    bands=["B02", "B03", "B04", "B05", "B06", "B07", "B08", "B8A", "B11", "B12"],
    start_date="2023-01-01",
    end_date="2023-12-31",
    edge_size=1024,
    resolution=10
)

# Prepare the data to be used in the model
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
original_s2_numpy = (da[11].compute().to_numpy() / 10_000).astype("float32")
X = torch.from_numpy(original_s2_numpy).float().to(device)
X = torch.nan_to_num(X, nan=0.0, posinf=0.0, neginf=0.0)

# Load the model
model = mlstac.load("model/SEN2SRLite").compiled_model(device=device)


# Apply model
superX = sen2sr.predict_large(
    model=model,
    X=X, # The input tensor
    overlap=32, # The overlap between the patches
)

Estimate the Local Attention Map

This example computes the Local Attention Map (LAM) to analyze the model's spatial sensitivity and robustness. The input image is scanned with a sliding window, and the model's attention is estimated across multiple upscaling factors. The resulting KDE map highlights regions where the model focuses more strongly, while the robustness vector quantifies the model's stability to spatial perturbations.

import mlstac
import sen2sr
import torch
import cubo

# Create a Sentinel-2 L2A data cube for a specific location and date range
da = cubo.create(
    lat=39.49152740347753,
    lon=-0.4308725142800361,
    collection="sentinel-2-l2a",
    bands=["B04", "B03", "B02", "B08"],
    start_date="2023-01-01",
    end_date="2023-12-31",
    edge_size=128,
    resolution=10
)


# Prepare the data to be used in the model
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
original_s2_numpy = (da[11].compute().to_numpy() / 10_000).astype("float32")
X = torch.from_numpy(original_s2_numpy).float().to(device)
X = torch.nan_to_num(X, nan=0.0, posinf=0.0, neginf=0.0)

# Load the model
#mlstac.download(
#  file="https://huggingface.co/tacofoundation/sen2sr/resolve/main/SEN2SRLite/NonReference_RGBN_x4/mlm.json",
#  output_dir="model/SEN2SRLite_RGBN",
#)
model = mlstac.load("model/SEN2SRLite_RGBN").compiled_model(device=device)

# Apply model
kde_map, complexity_metric, robustness_metric, robustness_vector = sen2sr.lam(
    X=X, # The input tensor
    model=model, # The SR model
    h=240, # The height of the window
    w=240, # The width of the window
    window=32, # The window size
    scales = ["2x", "3x", "4x", "5x", "6x"]
)


import matplotlib.pyplot as plt
fig, ax = plt.subplots(1, 2, figsize=(12, 6))
ax[0].imshow(kde_map)
ax[0].set_title("Kernel Density Estimation")
ax[1].plot(robustness_vector)
ax[1].set_title("Robustness Vector")
plt.show()

Metadata

Release files for sen2sr 0.8.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sen2sr 0.8.5
File Size Uploaded
sen2sr-0.8.5.tar.gz 38.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for sen2sr 0.8.5
File Interpreter ABI Platform
sen2sr-0.8.5-py3-none-any.whl Python 3 none any Details

Total release size: 79.8 kB

Release files / sen2sr-0.8.5.tar.gz

Download URL sen2sr-0.8.5.tar.gz
Size 38.5 kB
Tags Source
SHA-256 checksum
How to use checksums
36c7421d4362c2518db42dfe277428256c5a4dadc8546907329015ff76be4649
BLAKE2b-256 checksum
How to use checksums
21586f1d8e9f11071cc615a8dbb6f345f4ac9028bade86527fbd47198408e044
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.8.0 colorama/0.4.4 importlib-metadata/7.0.1 keyring/24.3.1 pkginfo/1.9.6 readme-renderer/34.0 requests-toolbelt/1.0.0 requests/2.32.3 rfc3986/1.5.0 tqdm/4.67.1 urllib3/2.3.0 CPython/3.10.12

Release files / sen2sr-0.8.5-py3-none-any.whl

Download URL sen2sr-0.8.5-py3-none-any.whl
Size 41.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2a5ecee722a23410fc838f2ae02b69d1d8f99b559073d4869593f420815f46a0
BLAKE2b-256 checksum
How to use checksums
e728ac5d3b3de15ed85fb23831488a08491bf1a5969d95357b8c0f25d2ef3ba9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.8.0 colorama/0.4.4 importlib-metadata/7.0.1 keyring/24.3.1 pkginfo/1.9.6 readme-renderer/34.0 requests-toolbelt/1.0.0 requests/2.32.3 rfc3986/1.5.0 tqdm/4.67.1 urllib3/2.3.0 CPython/3.10.12

Release history Release notifications | RSS feed

This release

0.8.5 This release

2 release files

0.8.0

2 release files

0.6.1

2 release files

0.5.0

2 release files

0.3.0

2 release files

0.2.9

2 release files

0.2.8

2 release files

0.2.7

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page