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!
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.
python
1import mlstac
2import torch
3import cubo
45# Download the model6mlstac.download(7file="https://huggingface.co/tacofoundation/sen2sr/resolve/main/SEN2SRLite/main/mlm.json",8 output_dir="model/SEN2SRLite",9)1011# Load the model12device = torch.device("cuda"if torch.cuda.is_available()else"cpu")13model = mlstac.load("model/SEN2SRLite").compiled_model(device=device)14model = model.to(device)1516# Create a Sentinel-2 L2A data cube for a specific location and date range17da = cubo.create(18 lat=39.49152740347753,19 lon=-0.4308725142800361,20 collection="sentinel-2-l2a",21 bands=["B02","B03","B04","B05","B06","B07","B08","B8A","B11","B12"],22 start_date="2023-01-01",23 end_date="2023-12-31",24 edge_size=128,25 resolution=1026)2728# Prepare the data to be used in the model, select just one sample 29device = torch.device("cuda"if torch.cuda.is_available()else"cpu")30original_s2_numpy =(da[11].compute().to_numpy()/10_000).astype("float32")31X = torch.from_numpy(original_s2_numpy).float().to(device)3233# Apply model34superX = 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.
python
1import mlstac
2import torch
3import cubo
45# Download the model6mlstac.download(7file="https://huggingface.co/tacofoundation/sen2sr/resolve/main/SEN2SRLite/NonReference_RGBN_x4/mlm.json",8 output_dir="model/SEN2SRLite_RGBN",9)1011# Create a Sentinel-2 L2A data cube for a specific location and date range12da = cubo.create(13 lat=39.49152740347753,14 lon=-0.4308725142800361,15 collection="sentinel-2-l2a",16 bands=["B04","B03","B02","B08"],17 start_date="2023-01-01",18 end_date="2023-12-31",19 edge_size=128,20 resolution=1021)222324# Prepare the data to be used in the model25device = torch.device("cuda"if torch.cuda.is_available()else"cpu")26original_s2_numpy =(da[11].compute().to_numpy()/10_000).astype("float32")27X = torch.from_numpy(original_s2_numpy).float().to(device)28X = torch.nan_to_num(X, nan=0.0, posinf=0.0, neginf=0.0)2930# Load the model31model = mlstac.load("model/SEN2SRLite_RGBN").compiled_model(device=device)3233# Apply model34superX = 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.
python
1import mlstac
2import torch
3import cubo
45# Download the model6mlstac.download(7file="https://huggingface.co/tacofoundation/sen2sr/resolve/main/SEN2SRLite/Reference_RSWIR_x2/mlm.json",8 output_dir="model/SEN2SRLite_Reference_RSWIR_x2",9)1011# Create a Sentinel-2 L2A data cube for a specific location and date range12da = cubo.create(13 lat=39.49152740347753,14 lon=-0.4308725142800361,15 collection="sentinel-2-l2a",16 bands=["B02","B03","B04","B05","B06","B07","B08","B8A","B11","B12"],17 start_date="2023-01-01",18 end_date="2023-12-31",19 edge_size=128,20 resolution=1021)2223# Prepare the data to be used in the model24device = torch.device("cuda"if torch.cuda.is_available()else"cpu")25original_s2_numpy =(da[11].compute().to_numpy()/10_000).astype("float32")26X = torch.from_numpy(original_s2_numpy).float().to(device)2728# Load the model29model = mlstac.load("model/SEN2SRLite_Reference_RSWIR_x2").compiled_model(device=device)30model = model.to(device)3132# Apply model33superX = 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.
python
1import mlstac
2import sen2sr
3import torch
4import cubo
56# Create a Sentinel-2 L2A data cube for a specific location and date range7da = cubo.create(8 lat=39.49152740347753,9 lon=-0.4308725142800361,10 collection="sentinel-2-l2a",11 bands=["B02","B03","B04","B05","B06","B07","B08","B8A","B11","B12"],12 start_date="2023-01-01",13 end_date="2023-12-31",14 edge_size=1024,15 resolution=1016)1718# Prepare the data to be used in the model19device = torch.device("cuda"if torch.cuda.is_available()else"cpu")20original_s2_numpy =(da[11].compute().to_numpy()/10_000).astype("float32")21X = torch.from_numpy(original_s2_numpy).float().to(device)22X = torch.nan_to_num(X, nan=0.0, posinf=0.0, neginf=0.0)2324# Load the model25model = mlstac.load("model/SEN2SRLite").compiled_model(device=device)262728# Apply model29superX = sen2sr.predict_large(30 model=model,31 X=X,# The input tensor32 overlap=32,# The overlap between the patches33)
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.
python
1import mlstac
2import sen2sr
3import torch
4import cubo
56# Create a Sentinel-2 L2A data cube for a specific location and date range7da = cubo.create(8 lat=39.49152740347753,9 lon=-0.4308725142800361,10 collection="sentinel-2-l2a",11 bands=["B04","B03","B02","B08"],12 start_date="2023-01-01",13 end_date="2023-12-31",14 edge_size=128,15 resolution=1016)171819# Prepare the data to be used in the model20device = torch.device("cuda"if torch.cuda.is_available()else"cpu")21original_s2_numpy =(da[11].compute().to_numpy()/10_000).astype("float32")22X = torch.from_numpy(original_s2_numpy).float().to(device)23X = torch.nan_to_num(X, nan=0.0, posinf=0.0, neginf=0.0)2425# Load the model26#mlstac.download(27# file="https://huggingface.co/tacofoundation/sen2sr/resolve/main/SEN2SRLite/NonReference_RGBN_x4/mlm.json",28# output_dir="model/SEN2SRLite_RGBN",29#)30model = mlstac.load("model/SEN2SRLite_RGBN").compiled_model(device=device)3132# Apply model33kde_map, complexity_metric, robustness_metric, robustness_vector = sen2sr.lam(34 X=X,# The input tensor35 model=model,# The SR model36 h=240,# The height of the window37 w=240,# The width of the window38 window=32,# The window size39 scales =["2x","3x","4x","5x","6x"]40)414243import matplotlib.pyplot as plt
44fig, ax = plt.subplots(1,2, figsize=(12,6))45ax[0].imshow(kde_map)46ax[0].set_title("Kernel Density Estimation")47ax[1].plot(robustness_vector)48ax[1].set_title("Robustness Vector")49plt.show()