Skip to content

zaitra/onboard-methane-detection

Repository files navigation

Onboard Methane Detection

This library provides an end-to-end pipeline for processing hyperspectral imagery to detect methane emissions. It includes tools for band selection, methane spectrum generation, preprocessing via Mag1c SAS, and model inference.

Citation arXiv:2606.03675

If you find our research useful, please cite our article:

@misc{herec2026fastmethanedetectionpipeline,
      title={A Fast Methane Detection Pipeline on Board Satellites Based on Mag1c-SAS and LinkNet}, 
      author={Jonáš Herec and Vít Růžička and Rado Pitoňák and Jan Sedmidubsky},
      year={2026},
      eprint={2606.03675},
      archivePrefix={arXiv},
      primaryClass={cs.CV},
      url={https://arxiv.org/abs/2606.03675}, 
}

Installation

pip install onboard-methane-detection

Dependencies and Performance

Onboard Methane Detection is lightweight and depends only on NumPy for processing. ONNX Runtime is required only if you want inference. You can omit ONNX Runtime by using the lightweight build (see Lightweight Onboard Package Build below).

Important: NumPy can be very slow without an acceleration library, so make sure one is installed on your device. We tested with OpenBLAS; the build was about 3.9 MB on ARM Cortex-A53 when compiled without LAPACK. After installing OpenBLAS, reinstall NumPy via pip so it can be detected and used.

End-to-End Example

The following example demonstrates a complete workflow, divided into distinct stages: on-ground preparation, and onboard session execution. The same example is available in showcase.ipynb .

On-Ground

# Core imports for on-ground processing
import numpy as np
from onboard_methane_detection import (
    select_the_bands_by_transmittance, 
    generate_methane_spectrum, 
    select_rgb_bands
)

# 1. Define or load sensor specifications
# wavelengths = [...]  # List of all available sensor wavelengths
# fwhms = [...]        # List of corresponding FWHMs

# 2. Select RGB bands
rgb_wavelengths, rgb_indices = select_rgb_bands(wavelengths)

# 3. Select bands specifically for Methane detection
# First, generate the baseline CH4 spectrum across all sensor bands
ch4_spectrum_full = generate_methane_spectrum(wavelengths, fwhms)

# Then, select the most informative bands based on transmittance
selected_wvs_ch4, selected_ch4_spectrum = select_the_bands_by_transmittance(
    wavelengths, ch4_spectrum_full, N=50, strategy="highest-variance"
)
selected_indices_ch4 = [wavelengths.tolist().index(w) for w in selected_wvs_ch4]

# 4. Export artifacts for the onboard inference session
np.save('rgb_indices.npy', np.array(rgb_indices))
np.save('selected_indices_ch4.npy', np.array(selected_indices_ch4))
np.save('selected_ch4_spectrum.npy', selected_ch4_spectrum)

Onboard

import numpy as np

# Core imports for onboard execution
from onboard_methane_detection import (
    mag1c_sas,
    initialize_model,
    normalize_image,
    model_inference
)

# 1. Load exported artifacts (indices and spectrum) from On-Ground preparation
rgb_indices = np.load('rgb_indices.npy')
selected_indices_ch4 = np.load('selected_indices_ch4.npy')
selected_ch4_spectrum = np.load('selected_ch4_spectrum.npy')

# 2. Session Initialization
# Initialize the inference model before the processing loop begins
session, input_name = initialize_model(dynamic_output_size=True)

# 3. Processing Images (Onboard Loop)
# acquired_images: list of images in shape (C, H, W)

for image in acquired_images:
    # Extract RGB channels using previously found indices
    rgb_image = image[rgb_indices, :, :]
    
    # Extract the CH4 detection bands from the image
    methane_bands_image = image[selected_indices_ch4, :, :]
    
    # Apply Mag1c SAS preprocessing.
    # Optional tiling args (`tiling`, `tile_size`) can be used if the image is too large.
    mag1c_output = mag1c_sas(methane_bands_image, selected_ch4_spectrum, tiling=False)
    
    # Concatenate Mag1c SAS output with local RGB context.
    # Correct channel order is R, G, B, Mag1c-SAS.
    model_input = np.concatenate([rgb_image, mag1c_output], axis=0)
    
    # Normalize input: sensor_or_factors can be "emit", "aviris_ng", 
    # or a custom array of 4 division factors for a different sensor.
    model_input = normalize_image(model_input, sensor_or_factors='emit') 
    
    # Run model inference.
    # Tiling arguments can also be provided here if the image is too large.
    predictions = model_inference(session, input_name, model_input, use_tiling=False, logits_to_probs=True)
    
    print("Processed image and generated predictions.")

Lightweight Onboard Package Build

For deployment on resource-constrained satellite hardware, you may want to build a minimal version of this library containing only the necessary modules. A deployment script build_package_for_deployment.py is provided for this purpose. The lightweight build depends only on NumPy, and adds ONNX Runtime only if you include inference.

Usage

Run the script to generate a lightweight installable package:

# Base-only build (no optional subpackages):
# Includes only `compute_base_mag1c_SAS` (Mag1c-SAS core math).
python build_package_for_deployment.py --output satellite_pkg

# Add optional subpackages as needed:
python build_package_for_deployment.py --parts processing inference --output satellite_pkg

What Gets Included

The build script always includes the base Mag1c-SAS implementation and then optionally adds subpackages. You can omit --parts entirely to keep the package as small as possible.

  • Base (always included):
    • Exports compute_base_mag1c_SAS(...) which expects batched, flattened radiance data shaped like (B, N, C).
    • Import path: from onboard_methane_detection import compute_base_mag1c_SAS
    • This is the minimal dependency footprint and is suitable if you already handle reshaping/masking/sampling in your own pipeline.
  • processing (optional):
    • Adds mag1c_sas(image, methane_spectrum, ...), a more convenient Mag1c-SAS wrapper for CHW hyperspectral cubes.
    • Automatically handles masking invalid pixels, reshaping CHW -> (B, N, C), sampling pixels for covariance estimation, and reshaping the output back.
  • inference (optional):
    • Adds LinkNet ONNX inference utilities: initialize_model(...), normalize_image(...), and model_inference(...).
    • model_inference(...) can use tiling, but tiling utilities live in processing, so include both inference and processing if you want tiled inference.
    • Use this when you want to run the segmentation model onboard.
  • onground (optional):
    • Adds on-ground preparation helpers: generate_methane_spectrum(...), select_the_bands_by_transmittance(...), and select_rgb_bands(...).
    • Use this to generate the methane spectrum template and select bands/indices to export for the onboard session.

Arguments

  • --parts: A space-separated list of optional subpackages to include in the build. Available options are inference, processing, and onground. If you want the smallest possible package, omit --parts entirely (base-only Mag1c-SAS).
  • --output: The destination directory where the lightweight package will be generated (default: satellite_package).
  • --source: The directory of the source package (default: onboard_methane_detection).

Once the package is generated, you can install it on your target hardware using:

pip install ./satellite_pkg

Acknowledgments

A huge thank you to the creators of Mag1c. This project uses core files and edited code from their original repository, and it wouldn't have been possible without their foundational work!

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors