Data Wrangling
This page covers small transformations that are useful after loading data or computing spectral indices.
Work With Raster DataArrays
Every Orthomosaic wraps an xarray.DataArray with shape:
Access it through mosaic.data. Use xarray and rioxarray methods directly when you need lower-level operations:
| data = mosaic.data
print(data.dims)
print(data.rio.crs)
print(data.rio.bounds())
|
Stretch Data For Display
Use VisualizationUtil directly when you need an image array instead of a plot.
| import numpy as np
from uavpy.util import VisualizationUtil
array = np.moveaxis(mosaic.data.compute().values, 0, -1)
rgb_image = VisualizationUtil.raster2image(
array,
rgb=(0, 1, 2),
stretch_method="percentiles",
)
|
raster2image expects a NumPy array shaped as (height, width, bands) and uses zero-based band indices. By contrast, Orthomosaic.plot(rgb=(1, 2, 3)) uses one-based band indices for user-facing plotting.
Normalize Or Scale Arrays
| from uavpy.util import MathUtil
normalized = MathUtil.normalize(array)
scaled = MathUtil.scale(array, min_val=0, max_val=255)
|
Camera Geometry Helpers
| from uavpy.util import MiscUtil
sensor_size = MiscUtil.sensor_dimensions(field_of_view=25, focal_length=25)
fov = MiscUtil.field_of_view(sensor_dimension=sensor_size, focal_length=25)
|
Crop By Vector Features
Use Orthomosaic.extract_plots for the common workflow:
| from uavpy.artifacts import ShapeFile
shape_file = ShapeFile("./data/project/shapefiles/march.shp")
plots = await mosaic.extract_plots(shape_file, plot_id_field="plot_id")
|
Each returned item is an Orthomosaic, so it can be plotted, indexed, or saved:
| for plot in plots:
plot.plot(rgb=(1, 2, 3), title=str(plot.attrs["plot_id"]))
plot.save(f"./data/outputs/plot_{plot.attrs['plot_id']}.tif", overwrite=True)
|
Vector Layers On Maps
ShapeFile can also provide vector data for mapwidgets.VectorLayer:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | import sys
from mapwidgets import MapViewer, VectorLayer
from PySide6.QtWidgets import QApplication
from uavpy.artifacts import ShapeFile
shape_file = ShapeFile("./data/project/shapefiles/march.shp")
await shape_file.load()
app = QApplication.instance() or QApplication(sys.argv[:1])
viewer = MapViewer(backend="maplibre").resize(1200, 800).show()
viewer.add_layer(
VectorLayer.from_shapefile(shape_file.path, id="plots", name="Plot boundaries"),
zoom_to=True,
)
viewer.wait_for_map_ready()
app.exec()
|
GDAL Utility Imports
GDALUtil is loaded lazily from uavpy.util because GDAL's Python bindings require native shared libraries to be available at import time.
| from uavpy.util import GDALUtil
|
If this import fails, verify native GDAL first: