sarpro 0.2.3

A high-performance Sentinel-1 Synthetic Aperture Radar (SAR) GRD product to image processor.
Documentation

SARPRO

A high-performance Sentinel-1 Synthetic Aperture Radar (SAR) GRD product to image processor written in Rust. SARPRO is designed for users and organizations who need fast, hassle-free processing of Sentinel-1 GRD products into GeoTIFF or JPEG formats, delivering excellent grayscale GeoTIFFs and grayscale or synthetic RGB JPEGs with minimal setup time.

Features

  • Sentinel-1 Support: Specialized for Sentinel-1 SAR GRD products
  • Multiple Interfaces: CLI, GUI, and library APIs
  • Blazing Fast Performance: Process dual-band 400MP GRD product images and scale to 4MP (2048x2048) synthetic RGB JPEG with reprojection and padding in just ~1.5 seconds on modern laptops (since v0.2.1, see CHANGELOG for performance details) THIS IS NOT A TYPO
  • Flexible Polarization: Support for VV, VH, HH, HV, multiband, and polarization operations (sum, difference, ratio, etc.)
  • Advanced Autoscaling: Multiple strategies including standard, robust, adaptive, and equalized
  • Batch Processing: Process multiple SAFE directories efficiently for ML workflows
  • Output Formats: TIFF and JPEG support with configurable bit depths
  • Memory Efficient: Optimized for processing large SAR datasets
  • I/O Optimized: Performance typically limited by disk I/O, not CPU processing
  • since v0.2.0 (unreleased): Can now reproject to any CRS and resample with nearest, bilinear, or cubic algorithms

CHANGELOG IS FIRST THING TO READ

Till the project in not version 1.0.0, always visit CHANGELOG.md for the full changelog. The updating aims to be complementary and not breaking were possible, yet the API is still experimental and may evolve. GUI most likely will be the first to be updated with new features and improvements.

Best Usage Practices

When to Use Each Interface

  • CLI: Ideal for server environments and remote processing. Perfect for batch processing large datasets ready for machine learning workflows. Connect remotely and process images in bulk with consistent, automated results.

  • GUI: Best for local work and interactive processing. Use when you need visual feedback, parameter experimentation, or one-off processing tasks on your local machine.

  • Library: For experimentation and when you need direct access to core processing functions. Integrate SARPRO capabilities into your own Rust applications.

Performance Expectations

SARPRO is optimized for bulk processing with exceptional performance:

  • Performance: Starting from v0.2.1 dramatic optimizations were made to the processing pipeline which you can see in the CHANGELOG. Now processing a dual-band 400MP SAR GRD product image and scaling it to 4MP (2048x2048) synthetic RGB JPEG with padding and reprojection takes approximately ~1.5 seconds on a modern laptop (Apple M4Pro12) with Tamed db autoscale strategy and cubic resampling. Setting reprojection to none will reduce the time to ~348.21 ms. And you might as well expect N x performance improvement in the cloud. Warping to the native resolution same dual-band 400MP SAR GRD product and into synthetic RGB JPEG takes x 12-14 or around 55 seconds. Non warping on the same product peaks around 40 seconds.
  • CPU vs I/O: Debug and release builds show negligible performance differences on the latest Apple Silicon laptops, indicating that your performance will typically be limited by I/O, not CPU
  • Scalability: Run multiple SARPRO or SARPRO UI instances in parallel — limited only by your system’s resources — to handle different workflows simultaneously.
  • Memory Usage: The memory impact is staged sequentially.
  • Error Resilience: The CLI and UI versions are made Error SAFE, which means it will not crash on errors (like no data available or data is corrupted, or wrong GRD product) no matter what.

Mount Fuji synthetic RGB crop example from the full 26544 × 26544px resolution processed by SARPRO in 50 seconds. Data: dataspace.copernicus.eu

Name: S1A_IW_GRDH_1SDV_20250706T204346_20250706T204411_059968_07730F_F70D.SAFE
Size: 1893MB
Sensing time: 2025-07-06T20:39:57.839576
Platform short name: SENTINEL-1
Instrument short name: SAR

Mount Fuji crop example

Recommended Workflows

  1. ML Pipeline Preparation: Use CLI batch mode to process large collections of Sentinel-1 data into consistent formats
  2. Quality Assessment: Use GUI for initial data exploration and parameter tuning
  3. Custom Integration: Use the library API for specialized processing chains or integration with existing systems

About using reprojection or not

Setting reprojection to --target-crs none or ommiting it preserves native geometry just as it is packed in the SAFE product.

When native/no-reprojection is useful:

  • Quantitative workflows that avoid resampling:
    • Change detection/ratios on same-orbit, same-processing GRDs handled by an external co-registration/RDTC step.
    • Preserving radiometry/speckle statistics (no interpolation).
  • Downstream processing that performs proper RDTC later (don’t warp twice).
  • Performance/throughput and reproducibility of pixel values for ML feature engineering.
  • Quicklooks where map-accurate alignment is not required.

Requirements

System Dependencies

SARPRO depends on GDAL (Geospatial Data Abstraction Library) for reading and processing geospatial data. This is the only critical dependency to install correctly.

macOS (using Homebrew)

# Install GDAL via Homebrew
brew install gdal

# Verify installation
gdalinfo --version

Environment Variables Setup:

After installing GDAL with Homebrew, you need to set up environment variables for the Rust build process:

# Add to your ~/.zshrc or ~/.bashrc
export GDAL_HOME=$(brew --prefix gdal)
export GDAL_INCLUDE_DIR=$GDAL_HOME/include
export GDAL_LIB_DIR=$GDAL_HOME/lib
export PKG_CONFIG_PATH=$GDAL_HOME/lib/pkgconfig:$PKG_CONFIG_PATH

# For Apple Silicon Macs, you might also need:
export LIBRARY_PATH=$GDAL_HOME/lib:$LIBRARY_PATH
export CPATH=$GDAL_HOME/include:$CPATH

Linux (Ubuntu/Debian)

# Install GDAL development packages
sudo apt update
sudo apt install libgdal-dev gdal-bin pkg-config

# Verify installation
gdalinfo --version

Other Platforms

For other platforms or custom installations, ensure:

  • GDAL development headers are available
  • pkg-config can find GDAL
  • Set GDAL_HOME, GDAL_LIB_DIR, and GDAL_INCLUDE_DIR environment variables if needed

Rust Toolchain

SARPRO requires Rust 2024 edition. Install Rust using rustup:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Installation

From Source

# Clone the repository
git clone https://github.com/bogwi/sarpro.git
cd sarpro

# Build the project
cargo build --release --features full

# The CLI binary will be available at target/release/sarpro
# The GUI binary will be available at target/release/sarproUI

Via Cargo (prebuilt install)

# Install CLI only (default features)
cargo install sarpro

# Install GUI binary (requires GDAL and GUI deps)
cargo install sarpro --features gui --bin sarproUI

Note: Installing the GUI requires the GDAL runtime and GUI dependencies to be available on your system.

Usage

Command Line Interface (CLI)

The CLI provides powerful batch processing capabilities for SAR imagery, optimized for cloud environments and ML pipeline preparation. Perfect for remote processing and bulk operations.

Usage Examples


# Batch process a directory
cargo run --release --bin sarpro -- --input-dir /path/to/safe/directories --output-dir /path/to/output --batch --log --format jpeg --polarization multiband --size 1024 --autoscale tamed --target-crs EPSG:32630 --resample-alg bilinear

# Process a .SAFE file with specific parameters
cargo run --release --bin sarpro -- -i data.SAFE -o output.tiff \
    --polarization multiband \
    --format tiff \
    --bit-depth u16 \
    --size 1024 \
    --autoscale tamed \
    --target-crs EPSG:32630 \
    --resample-alg bilinear \
    --log

Available Options

  • --input, -i: Input SAFE directory (single file mode)

  • --input-dir: Input directory containing SAFE subdirectories (batch mode)

  • --output, -o: Output filename (single file mode)

  • --output-dir: Output directory for batch processing

  • --format, -f: Output format (tiff or jpeg)

  • --bit-depth: Output bit depth (8 or 16)

  • --polarization: Polarization mode (vv, vh, hh, hv, multiband, sum, diff, ratio, n-diff, log-ratio)

  • --autoscale: Autoscaling strategy (standard, robust, adaptive, equalized, tamed, default)

  • --size: Output image size (predefined: 512, 1024, 2048, or custom number, or original)

  • --pad: Add padding to make square images

  • --batch: Enable batch mode with error resilience

  • --log: Enable detailed logging

  • --target-crs: Optional target CRS for map reprojection (e.g., EPSG:4326, EPSG:32633); use none to disable reprojection explicitly

  • --resample-alg: Resampling algorithm for reprojection (nearest, bilinear, cubic) — default: bilinear

Graphical User Interface (GUI)

Launch the GUI application for interactive local processing and experimentation:

  • Start the GUI from the command line:
cargo run --release --bin sarproUI --features gui

or double click the executable here: target/release/sarproUI if you have built the project with the full feature.

The GUI is ideal for local work and provides:

  • File browser for selecting SAFE directories
  • Interactive parameter adjustment
  • Real-time preview and visual feedback
  • Progress monitoring
  • Export/import of configuration presets
  • CLI command generation
  • TRACE, DEBUG, INFO, WARN, ERROR, logging levels
  • System CPU and memory usage monitoring

Screenshots and examples

SARPRO GUI

The GUI is the easiest way to get started with SARPRO locally.

SARPRO GUI

Render example of Sentinel-1 SAR GRD product downloaded from dataspace.copernicus.eu. The 25192 × 19614px (~500MP) reprojected, dual-band image scaled and padded to 3024px on the long side and carrying metadata took just ~2 seconds on Apple M4Pro12 with minimal CPU usage. (see CHANGELOG from v0.2.1 for performance details). Warping it at 25192 × 19614px, and autocaling, padding and into synthetic RGB JPEG takes around 70 seconds.

Name: S1C_IW_GRDH_1SDV_20250730T142348_20250730T142417_003451_006EEA_895D.SAFE
Size: 1893MB
Sensing time: 2025-07-30T14:23:48.452000Z
Platform short name: SENTINEL-1
Instrument short name: SAR

Synthetic RGB

Create good lookers using synthetic RGB JPEGs in a few clicks.

synRGB

Multiband

Get what you need in classic multi-band Grayscale TIFFs, quickly.

multiband

As a Library

SARPRO provides a typed, ergonomic Rust API for integrating Sentinel-1 GRD processing into your applications. The API is built on top of the working MVP used by the CLI/GUI and is robust, but still early and may evolve.

Note on stability: the public API is experimental in initial releases. Expect incremental improvements as the project stabilizes. Breaking changes may occur; consult the changelog and docs.

Add dependency

[dependencies]
sarpro = { version = "0.1", features = ["full"] }

High-level processing to a file

use std::path::Path;
use sarpro::{
    api::process_safe_to_path,
    ProcessingParams,
    AutoscaleStrategy, BitDepthArg, OutputFormat, Polarization,
};

let params = ProcessingParams {
    format: OutputFormat::TIFF,
    bit_depth: BitDepthArg::U16,
    polarization: Polarization::Multiband,
    autoscale: AutoscaleStrategy::Tamed,
    size: Some(2048),
    pad: true,
};

process_safe_to_path(
    Path::new("/data/S1A_xxx.SAFE"),
    Path::new("/out/product.tiff"),
    &params,
)?;

In-memory processing to raw buffers

use std::path::Path;
use sarpro::{
    api::process_safe_to_buffer,
    AutoscaleStrategy, BitDepth, OutputFormat, Polarization,
};

let img = process_safe_to_buffer(
    Path::new("/data/S1A_xxx.SAFE"),
    Polarization::Multiband,
    AutoscaleStrategy::Tamed,
    BitDepth::U8,            // Controls buffer bit depth for TIFF paths
    Some(1024),              // Resize target
    true,                    // Pad to square
    OutputFormat::JPEG,      // JPEG for synthetic RGB; TIFF for grayscale/multiband
)?;

match (img.format, img.bit_depth) {
    (OutputFormat::JPEG, _) => {
        // Synthetic RGB (interleaved RGB u8)
        let rgb: &[u8] = img.rgb.as_ref().unwrap();
        // Use in your pipeline...
    }
    (OutputFormat::TIFF, sarpro::BitDepth::U8) => {
        // Single-band or multiband u8
        let band1 = img.gray.as_ref();
        let band2 = img.gray_band2.as_ref();
    }
    (OutputFormat::TIFF, sarpro::BitDepth::U16) => {
        // Single-band or multiband u16
        let band1 = img.gray16.as_ref();
        let band2 = img.gray16_band2.as_ref();
    }
}

Typed save helpers (when you have complex arrays already)

use std::path::Path;
use ndarray::Array2;
use num_complex::Complex;
use sarpro::{
    api::{save_image, save_multiband_image},
    AutoscaleStrategy, BitDepth, OutputFormat, ProcessingOperation,
};

fn save_single(processed: &Array2<Complex<f64>>) -> sarpro::Result<()> {
    save_image(
        processed,
        Path::new("/out/single.tiff"),
        OutputFormat::TIFF,
        BitDepth::U16,
        Some(2048),
        None,                  // Optional SAFE metadata if available
        true,
        AutoscaleStrategy::Tamed,
        ProcessingOperation::SingleBand,
    )
}

fn save_dual(vv: &Array2<Complex<f64>>, vh: &Array2<Complex<f64>>) -> sarpro::Result<()> {
    save_multiband_image(
        vv,
        vh,
        Path::new("/out/multiband.tiff"),
        OutputFormat::TIFF,
        BitDepth::U8,
        Some(1024),
        None,
        true,
        AutoscaleStrategy::Tamed,
        ProcessingOperation::MultibandVvVh,
    )
}

Batch helpers

use std::path::Path;
use sarpro::{api::{iterate_safe_products, process_directory_to_path}, ProcessingParams, AutoscaleStrategy, BitDepthArg, OutputFormat, Polarization};

let params = ProcessingParams {
    format: OutputFormat::JPEG,
    bit_depth: BitDepthArg::U8,
    polarization: Polarization::Multiband,
    autoscale: AutoscaleStrategy::Tamed,
    size: Some(1024),
    pad: true,
};

let report = process_directory_to_path(
    Path::new("/data/safe_dir"),
    Path::new("/out"),
    &params,
    true, // continue_on_error
)?;

println!("processed={}, skipped={}, errors={}", report.processed, report.skipped, report.errors);

Supported Data

  • Input Formats: Sentinel-1 SAFE directories (GRD products)
  • Polarizations: VV, VH, HH, HV, and combinations
  • Product Types: Ground Range Detected (GRD)
  • Output Formats: GeoTIFF, JPEG

Product assumptions and processing pipeline

What official Sentinel‑1 GRD already includes

  • Radiometric calibration: Yes — DN values are converted to backscatter coefficients (σ⁰/β⁰/γ⁰) in ESA’s GRD chain
  • Thermal noise removal: Yes — applied since IPF 2.9 (2018+)
  • Multilooking & ground‑range projection: Yes — GRD is multilooked and in ground‑range geometry
  • Range‑Doppler Terrain Correction (orthorectification): No — GRD remains in radar geometry without RDTC

What SARPRO does and does not do

  • SARPRO does not perform RDTC/orthorectification or DEM‑based terrain correction
  • Optional map reprojection: If --target-crs is set, SARPRO uses GDAL gdalwarp to reproject using the product’s georeferencing (and falls back to GCP + -tps if needed). This improves map alignment in many cases but is not a substitute for full RDTC
  • Core image steps: magnitude→dB conversion, SAR‑tuned autoscaling, optional resize/pad, then write GeoTIFF or JPEG with metadata. TIFF embeds georeferencing; JPEG is accompanied by .json, .jgw/.wld, and .prj sidecars

Processing flow

flowchart TB
  A["Input: Sentinel-1 SAFE (GRD)"] --> B["Parse manifest.safe + annotation XMLs\nExtract product & georef metadata"]
  A --> C["Identify polarization measurement TIFFs (VV/VH/HH/HV)"]
  C --> D["Read TIFF via GDAL\narray + geotransform + projection/GCP"]
  D --> E{"Target CRS specified?"}
  E -- "Yes" --> F["Warp with gdalwarp to target CRS\n-r nearest/bilinear/cubic\nIf no SRS: use GCP + -tps"]
  E -- "No" --> G["Use native georeferencing"]
  F --> H["Optional polarization ops\nsum/diff/ratio/n-diff/log-ratio or pair for synRGB"]
  G --> H
  H --> I["Convert magnitude to dB\n10·log10(|x|) and mask invalid"]
  I --> J["Autoscale to U8/U16 using strategy\nstandard/robust/adaptive/equalized/tamed"]
  J --> K["Optional resize (long side)"]
  K --> L["Optional pad to square"]
  L --> M{"Output format"}
  M -- "TIFF (u8/u16)" --> N["Write GeoTIFF bands"]
  N --> O["Embed metadata (geotransform/projection + attributes)"]
  M -- "JPEG (gray/synRGB)" --> P["Write JPEG"]
  P --> Q["Sidecars: .json (metadata), .jgw/.wld, .prj"]

Roadmap

Before v1.0.0

  • Enhanced Color Combinations: Additional color schemes similar to Copernicus Browser
  • Tiling Support: Divide large SAR scenes into smaller tiles for easier processing and ML training
  • Parallel Workflows: Multiple independent conversion processes running simultaneously within the same application
  • Polarimetric Indices: Complete support for advanced indices including RVI, PR, CPD, and more
  • RDTC/orthorectification | DEM‑based terrain correction: yes.

Future Versions

  • v2.x: Possible SLC (Single Look Complex) product support
  • v3.x: Possible Level-0 RAW support for advanced users

Troubleshooting (GDAL)

  • If the build fails to find GDAL, ensure pkg-config locates it (pkg-config --libs gdal) and the environment variables in this README are exported in your shell.
  • On macOS, confirm brew --prefix gdal resolves and paths are set for both compile and runtime (DYLD_LIBRARY_PATH may also be needed when running outside Cargo).
  • On Linux, verify libgdal-dev and gdal-bin are installed and the GDAL version is supported by the crate.

License

This project is dual-licensed under MIT OR Apache-2.0.

Support

Acknowledgments

SARPRO is built with:

  • GDAL for geospatial data processing
  • ndarray for numerical computing
  • eframe for the GUI
  • clap for command-line parsing