Skip to content

Repository files navigation

uavpy

Code style: black Contributions welcome

UavPy is an open-source Python package for processing and analyzing UAV imagery. It provides a small, high-level API for loading orthomosaics, stacking raster bands, computing spectral indices, extracting plot-level regions of interest, and visualizing geospatial raster data.

The package builds on established geospatial and scientific Python libraries, including GDAL, rasterio, Fiona, NumPy, SciPy, and scikit-image.

Main Features

  • Raster artifact API: Load GeoTIFF orthomosaics and keep raster metadata through lazy rioxarray artifacts.
  • Band stacking: Combine multiple single-band rasters into a multi-band orthomosaic.
  • Spectral indices: Compute NDVI, NDRE, EVI, SAVI, or custom band math expressions such as B1/(B1+B2+B3).
  • Plot extraction: Crop orthomosaics into feature-level regions of interest from vector geometry.
  • Map integration: Display saved GeoTIFFs and vector boundaries with mapwidgets raster and vector layers.
  • Visualization helpers: Stretch, colormap, and render single-band or RGB raster data for quick inspection.

Requirements

UavPy requires Python 3.10 or newer.

GDAL is a native dependency. The Python GDAL binding must match the installed native GDAL library. In this checkout, pyproject.toml pins:

gdal==3.13.1

On macOS with Homebrew GDAL, make sure gdal-config is on PATH before syncing:

PATH="/opt/homebrew/bin:$PATH" uv sync

Install for Development

uv sync

If uv sync cannot find gdal-config, install GDAL development headers and ensure the matching gdal-config executable is on PATH.

Install the optional map viewer dependencies when using mapwidgets.MapViewer:

uv sync --extra widgets

Quick Start

1. Import Modules

from uavpy.artifacts import Orthomosaic, DSM, DTM
from uavpy.tools import SpectralIndex
from uavpy.util import VisualizationUtil as vis, MiscUtil

2. Load Data

mosaic = Orthomosaic.from_path("./data/orthomosaic.tif")
await mosaic.load()

print(mosaic.shape)
print(mosaic.band_info)

3. Inspect Bands

Band indexes are one-based in the public plotting and spectral-index APIs. Check the raster metadata before choosing display bands or index formulas:

for band in mosaic.band_info:
    print(band)

4. Compute Spectral Indices

ndvi = await SpectralIndex.ndvi(nir=4, red=1)(mosaic)
print(ndvi.min(), ndvi.max())

index = SpectralIndex("B1/(B1+B2+B3)")
result = await index(mosaic)

Spectral index computation returns a single-band Orthomosaic, which can be plotted, saved, or passed to downstream geospatial workflows.

Interactive Maps

UavPy uses the external mapwidgets package for interactive maps and GeoTIFF tile generation. Save or point to a GeoTIFF, then create a RasterLayer with the backend that fits the raster:

from pathlib import Path
import sys

from mapwidgets import MapViewer, RasterLayer
from PySide6.QtWidgets import QApplication

tile_layer = RasterLayer.from_tiled_geotiff(
    "./data/rgb_orthomosaic.tif",
    output_dir=Path(".uavpy_tiles/rgb_orthomosaic"),
    bands=(1, 2, 3),
    zoom_levels=range(18, 22),
    backend="gdal",
    overwrite=True,
)

app = QApplication.instance() or QApplication(sys.argv[:1])
viewer = MapViewer(backend="maplibre").resize(1200, 800).show()
viewer.add_layer(tile_layer, zoom_to=True)
viewer.wait_for_map_ready()
app.exec()

Use backend="gdal" for normal source-order RGB GeoTIFFs. Use backend="python" for arbitrary band selections, colormaps, or transparency masks:

tile_layer = RasterLayer.from_tiled_geotiff(
    "./data/multispectral_orthomosaic.tif",
    output_dir=Path(".uavpy_tiles/false_color"),
    bands=(6, 4, 2),
    zoom_levels=range(18, 22),
    backend="python",
    overwrite=True,
)

See the mapwidgets documentation for the full raster tiling API.

Huge Rasters

Very large orthomosaics need a different preparation step before tile generation. A 10 GB raster that is stored as scanline strips and has no internal overviews can be extremely slow because every map tile may require expensive random reads from the original image.

Before tiling huge rasters, convert them to a Cloud Optimized GeoTIFF (COG) from Python:

from uavpy.artifacts import Orthomosaic

raster = Orthomosaic.from_path("input_orthomosaic.tif")
optimized = raster.save_cog(
    "input_orthomosaic_cog.tif",
    overwrite=True,
)

This is equivalent to running gdal_translate -of COG with practical defaults:

  • BIGTIFF=YES allows output files larger than 4 GB.
  • COMPRESS=DEFLATE applies lossless compression. This preserves pixel values but may take longer than LZW.
  • BLOCKSIZE=512 stores the raster in 512 x 512 internal tiles instead of long scanline strips. This makes map-tile reads much faster.
  • OVERVIEWS=AUTO builds lower-resolution internal pyramids so low and medium zoom levels do not need to read full-resolution pixels.
  • NUM_THREADS=ALL_CPUS lets GDAL use all CPU cores during conversion.

These parameters are defaults, not fixed rules. Keep lossless compression such as DEFLATE, LZW, or ZSTD for analytical rasters. For visual-only RGB products, lossy compression such as JPEG may be acceptable if smaller files matter more than exact pixel values.

This conversion does not reduce the native orthomosaic resolution. Pixel size, width, height, CRS, bounds, and bands are preserved unless you explicitly pass resampling options such as -tr or -outsize.

To inspect whether a raster is already tiled and has overviews:

gdalinfo input_orthomosaic.tif

Look for Block=512x512 or similar tiled blocks and an Overviews: section.

5. Extract Plot-Level Regions

shape_file = ShapeFile("./data/plots.shp")
plots = await mosaic.extract_plots(shape_file, plot_id_field="plot_id")
for plot in plots:
    plot_ndvi = await ndvi(plot)
    print(plot.attrs["plot_id"], plot.attrs, plot_ndvi.min(), plot_ndvi.max())

Project Layout

  • mkdocs/ - Editable documentation source.
  • docs/ - Generated static documentation output.
  • uavpy/ - Root library folder
    • artifacts - Processing artifacts
    • decor - Internal decorators
    • map - Convenience re-exports for mapwidgets schemas and layers
    • tools - Spectral index and expression parsing tools
    • util - Raster, array, math, and visualization utilities

Useful Commands

  • uv sync - Install the project and development dependencies.
  • uv run pytest - Run the test suite.
  • uv run mkdocs serve - Start the live-reloading docs server.
  • uv run mkdocs build - Build the documentation site.
  • uv run python examples/demo.py - List the focused runnable examples.

Citing UavPy

To cite this project: BibTeX

@software{uavpy,
    author = {Henry Ruiz},
    title = {UavPy: High level Python API for UAV imagery data processing},
    url = {https://github.com/haruiz/uavpy},
    version = {0.1.0},
    year = {2020},
}

About

UavPy is a Python toolkit for working with UAV data across the remote-sensing workflow. It helps load and organize drone-derived datasets, process raster products like orthomosaics, compute spectral indices, extract plot-level measurements, and visualize geospatial outputs for field and research applications.

Resources

Contributing

Security policy

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages