Skip to content

Commit

Permalink
Merge pull request #15 from leftfield-geospatial/feature_refine_gcp
Browse files Browse the repository at this point in the history
Feature refine RPC & pan sharpen
  • Loading branch information
dugalh authored Sep 7, 2024
2 parents 1c06df6 + 821395e commit 5b4bfcf
Show file tree
Hide file tree
Showing 72 changed files with 4,470 additions and 1,194 deletions.
37 changes: 33 additions & 4 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Orthority

.. description_start
Orthority provides a command line interface and Python API for orthorectifying drone, aerial and satellite imagery, given a camera model and DEM. It supports common frame, and RPC camera models. Camera parameters can be read from various file formats, or image tags.
Orthority provides a command line toolkit and Python API for orthorectifying drone, aerial and satellite imagery, given a camera model and DEM. It supports common frame, and RPC camera models. Camera parameters can be read from various file formats, or image tags. Related algorithms including RPC refinement and pan-sharpening, are also provided.

.. description_end
Expand Down Expand Up @@ -49,6 +49,7 @@ Orthority command line functionality is accessed with the ``oty`` command, and i
- ``exif``: Orthorectify images with frame camera model(s) defined by image EXIF / XMP tags.
- ``odm``: Orthorectify images in a processed OpenDroneMap dataset that includes a DSM.
- ``rpc``: Orthorectify images with RPC camera models defined by image tags / sidecar files or parameter files.
- ``sharpen``: Pan sharpen an image using the Gram-Schmidt method.

Get help on ``oty`` with:

Expand Down Expand Up @@ -103,6 +104,19 @@ Orthorectify ``source.tif`` with the DEM in ``dem.tif``, and RPC camera model de
oty rpc --dem dem.tif source.tif
As above, but refine the RPC camera model with GCPs in ``source.tif`` tags:

.. code-block:: bash
oty rpc --dem dem.tif --gcp-refine tags source.tif
Pan sharpen the multispectral image ``ms.tif`` with the panchromatic image ``pan.tif``:

.. code-block:: bash
oty sharpen --pan pan.tif --multispectral ms.tif --out-file pan_sharp.tif
API
~~~

Expand All @@ -115,9 +129,7 @@ Orthorectify an image using interior and exterior parameter files to generate th
import orthority as oty
# URLs of required files
url_root = (
'https://raw.githubusercontent.com/leftfield-geospatial/orthority/main/tests/data/'
)
url_root = 'https://raw.githubusercontent.com/leftfield-geospatial/orthority/main/tests/data/'
src_file = url_root + 'ngi/3324c_2015_1004_05_0182_RGB.tif' # aerial image
dem_file = url_root + 'ngi/dem.tif' # DEM covering imaged area
int_param_file = url_root + 'io/ngi_int_param.yaml' # interior parameters
Expand All @@ -132,6 +144,23 @@ Orthorectify an image using interior and exterior parameter files to generate th
ortho.process('ortho.tif')
Pan sharpen a multispectral image with the matching panchromatic image:

.. below copied from docs/scripts/api_pan_sharp.py
.. code-block:: python
import orthority as oty
# URLs of required files
url_root = 'https://raw.githubusercontent.com/leftfield-geospatial/orthority/main/tests/data/'
pan_file = url_root + 'pan_sharp/pan.tif' # panchromatic drone image
ms_file = url_root + 'pan_sharp/ms.tif' # multispectral (RGB) drone image
# create PanSharpen object and pan sharpen
pan_sharp = oty.PanSharpen(pan_file, ms_file)
pan_sharp.process('pan_sharp.tif')
Documentation
-------------

Expand Down
2 changes: 1 addition & 1 deletion docs/api/camera.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Camera Models
Camera models
=============

.. automodule:: orthority.camera
Expand Down
6 changes: 6 additions & 0 deletions docs/api/fit.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Camera model fitting
====================

.. automodule:: orthority.fit
:members:
:show-inheritance:
6 changes: 6 additions & 0 deletions docs/api/pan_sharp.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Pan sharpening
===============

.. automodule:: orthority.pan_sharp
:members:
:show-inheritance:
7 changes: 3 additions & 4 deletions docs/background/camera_models.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Camera models
=============

A camera model describes the relationship between 3D :ref:`world <background/coordinates:world coordinates>` and 2D :ref:`pixel <background/coordinates:pixel coordinates>` coordinates.
A camera model describes the relationship between 3D :ref:`world <background/coordinates:world coordinates>` and 2D :ref:`pixel <background/coordinates:pixel coordinates>` coordinates. Model parameters can be specified with supported :doc:`files <../file_formats/index>`, or directly with the :mod:`~orthority.camera` API.

Frame cameras
-------------
Expand All @@ -11,13 +11,12 @@ Orthority uses the term *frame camera* for area-scan cameras like those used in
Interior parameters
~~~~~~~~~~~~~~~~~~~

The *interior* component describes the relationship between :ref:`camera <background/coordinates:camera coordinates>` and :ref:`pixel <background/coordinates:pixel coordinates>` coordinates. It depends on the interior geometry and optical properties of the camera. Interior parameters are: image size, focal length, sensor size, principal point and distortion coefficients. Parameter values can be specified with supported :doc:`files <../file_formats/index>`, or directly with the :mod:`~orthority.camera` API.
The *interior* component describes the relationship between :ref:`camera <background/coordinates:camera coordinates>` and :ref:`pixel <background/coordinates:pixel coordinates>` coordinates. It depends on the interior geometry and optical properties of the camera. Interior parameters are: image size, focal length, sensor size, principal point and distortion coefficients.

Exterior parameters
~~~~~~~~~~~~~~~~~~~

The *exterior* component describes the relationship between :ref:`world <background/coordinates:world coordinates>` and :ref:`camera <background/coordinates:camera coordinates>` coordinates. It is an affine transform consisting of a translation and rotation. Orthority represents exterior parameters as a world coordinate (*x*, *y*, *z*) camera position, and (*omega*, *phi*, *kappa*) camera orientation, where the (*omega*, *phi*, *kappa*) angles rotate from camera to world coordinates. Parameter values can be read from supported :doc:`files <../file_formats/index>`, or specified directly with the :mod:`~orthority.camera` API.

The *exterior* component describes the relationship between :ref:`world <background/coordinates:world coordinates>` and :ref:`camera <background/coordinates:camera coordinates>` coordinates. It is an affine transform consisting of a translation and rotation. Orthority represents exterior parameters as a world coordinate (*x*, *y*, *z*) camera position, and (*omega*, *phi*, *kappa*) camera orientation, where the (*omega*, *phi*, *kappa*) angles rotate from camera to world coordinates.

RPC cameras
-----------
Expand Down
1 change: 1 addition & 0 deletions docs/cli/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ Command line reference
exif
odm
rpc
sharpen
simple_ortho
2 changes: 2 additions & 0 deletions docs/cli/sharpen.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.. click:: orthority.cli:sharpen
:prog: oty sharpen
4 changes: 2 additions & 2 deletions docs/file_formats/exif_xmp.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
EXIF / XMP tags
===============
Image EXIF / XMP tags
=====================

:ref:`Frame camera <background/camera_models:frame cameras>` interior and exterior parameters can be read from image EXIF / XMP tags. The tables below list required tag sets. If more than one set is present, the first complete set is used.

Expand Down
6 changes: 6 additions & 0 deletions docs/file_formats/image_gcps.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.. include:: ../shared.txt

Image GCP tags
==============

GCPs can read from image tags. This capability is provided by the Rasterio_ / GDAL_ package. GCP pixel coordinates should use the :ref:`Orthority convention <background/coordinates:pixel coordinates>`.
4 changes: 3 additions & 1 deletion docs/file_formats/index.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
File formats
============

Camera model file formats supported by Orthority:
Camera model and related file formats supported by Orthority:

.. toctree::
:maxdepth: 1
Expand All @@ -14,6 +14,8 @@ Camera model file formats supported by Orthority:
image_rpc
oty_rpc
legacy
image_gcps
oty_gcps

.. note::

Expand Down
49 changes: 49 additions & 0 deletions docs/file_formats/oty_gcps.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
Orthority GCPs
==============

The native Orthority GCP format is a standard GeoJSON ``FeatureCollection`` of ``Point`` features, that can be visualised in a GIS. Each ``Feature`` is a GCP, where the geometry is its position in 3D WGS84 geographic coordinates. ``Feature`` properties are as follows:

.. list-table::
:widths: auto
:header-rows: 1

* - Property
- Value
* - ``filename``
- Image file name excluding parent path, with or without extension.
* - ``ji``
- Image ``[j, i]`` position in :ref:`pixel coordinates <background/coordinates:pixel coordinates>`.
* - ``id``
- ID string (optional).
* - ``info``
- Information string (optional).

An example file defining a single GCP:

.. code-block:: json
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"filename": "qb2_basic1b.tif",
"ji": [
821.3001696660183,
62.303697728645055
],
"id": "concrete-plinth-70",
"info": "concrete-plinth-70"
},
"geometry": {
"type": "Point",
"coordinates": [
24.41948061951812,
-33.65426900104435,
214.75143153141929
]
}
}
]
}
45 changes: 41 additions & 4 deletions docs/getting_started/api/camera.rst
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ The ``cam_kwargs`` argument can be used in :class:`~orthority.factory.FrameCamer
Model export
~~~~~~~~~~~~

Camera model parameters can be exported to Orthority format :doc:`interior <../../file_formats/oty_int>` and :doc:`exterior <../../file_formats/oty_ext>` parameter files with :meth:`~orthority.factory.RpcCameras.write_param`:
Camera model parameters can be exported to Orthority format :doc:`interior <../../file_formats/oty_int>` and :doc:`exterior <../../file_formats/oty_ext>` parameter files with :meth:`~orthority.factory.FrameCameras.write_param`:

.. literalinclude:: ../../scripts/api_frame.py
:language: python
Expand Down Expand Up @@ -100,7 +100,7 @@ Camera models can also be created from :doc:`image RPC tags / sidecar files <../
Parameter IO
~~~~~~~~~~~~

The ``io_kwargs`` argument can be used in :meth:`~orthority.factory.RpcCameras.from_images` to pass keyword arguments to :meth:`~orthority.param_io.read_im_rpc_param`.
Internally, the :func:`~orthority.param_io.read_im_rpc_param` function is used to read image RPC tags / sidecar files. The ``io_kwargs`` argument can be used in :meth:`~orthority.factory.RpcCameras.from_images` to pass keyword arguments to :func:`~orthority.param_io.read_im_rpc_param`.

E.g. to display a progress bar while reading image RPC tags / sidecar files:

Expand All @@ -112,20 +112,57 @@ E.g. to display a progress bar while reading image RPC tags / sidecar files:
Camera options
~~~~~~~~~~~~~~

The ``cam_kwargs`` argument can be used in :class:`~orthority.factory.RpcCameras` or :meth:`~orthority.factory.RpcCameras.from_images` to pass keyword arguments to :class:`~orthority.camera.RpcCamera`. E.g. to pass the world / ortho ``crs`` argument:
The ``cam_kwargs`` argument can be used in :class:`~orthority.factory.RpcCameras` or :meth:`~orthority.factory.RpcCameras.from_images` to pass keyword arguments to :class:`~orthority.camera.RpcCamera`. E.g. to specify a world / ortho ``crs``:

.. literalinclude:: ../../scripts/api_rpc.py
:language: python
:start-after: [cam_kwargs]
:end-before: [end cam_kwargs]

Model refinement
~~~~~~~~~~~~~~~~

RPC models can be refined with GCPs using the :meth:`~orthority.factory.RpcCameras.refine` method. GCPs can be read from an :doc:`Orthority GCPs file <../../file_formats/oty_gcps>`:

.. literalinclude:: ../../scripts/api_rpc.py
:language: python
:start-after: [refine]
:end-before: [end refine]

Or GCPs can be read from :doc:`image tags <../../file_formats/image_gcps>`:

.. literalinclude:: ../../scripts/api_rpc.py
:language: python
:start-after: [refine tag]
:end-before: [end refine tag]

The :func:`~orthority.param_io.read_im_gcps` function is used internally to read GCPs from image tags. ``io_kwargs`` can be used in :meth:`~orthority.factory.RpcCameras.refine` to pass keyword arguments to :func:`~orthority.param_io.read_im_gcps` when GCPs are supplied in image tags:

.. literalinclude:: ../../scripts/api_rpc.py
:language: python
:start-after: [refine io_kwargs]
:end-before: [end refine io_kwargs]

The :func:`~orthority.fit.refine_rpc` function is used internally to perform RPC refinement. ``fit_kwargs`` can be used in :meth:`~orthority.factory.RpcCameras.refine` to pass keyword arguments to :func:`~orthority.fit.refine_rpc`:

.. literalinclude:: ../../scripts/api_rpc.py
:language: python
:start-after: [refine fit_kwargs]
:end-before: [end refine fit_kwargs]

Model export
~~~~~~~~~~~~

Camera model parameters can be exported to a :doc:`Orthority RPC parameter file <../../file_formats/oty_rpc>` with :meth:`~orthority.factory.RpcCameras.write_param`:
Camera model parameters can be exported to an :doc:`Orthority RPC parameter file <../../file_formats/oty_rpc>` with :meth:`~orthority.factory.RpcCameras.write_param`:

.. literalinclude:: ../../scripts/api_rpc.py
:language: python
:start-after: [export]
:end-before: [end export]

When the models have been refined, :meth:`~orthority.factory.RpcCameras.write_param` exports the refined models together with the GCPs used to refine them. GCPs are written to an :doc:`Orthority GCPs file <../../file_formats/oty_gcps>`:

.. literalinclude:: ../../scripts/api_rpc.py
:language: python
:start-after: [export gcps]
:end-before: [end export gcps]
3 changes: 3 additions & 0 deletions docs/getting_started/api/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ Or, with conda_:
conda install -c conda-forge requests aiohttp
.. note::

If you're using the Orthority and Rasterio_ packages together, Orthority should be imported first to configure the PROJ setting for :doc:`vertical CRS transformations <../../background/vertical_crs>`.
Expand All @@ -24,3 +26,4 @@ Or, with conda_:

camera
ortho
pan_sharp
2 changes: 1 addition & 1 deletion docs/getting_started/api/ortho.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Orthorectification
==================

Orthorectification is performed by the :class:`~orthority.ortho.Ortho` class, which requires a source image, DEM, camera model and world / ortho CRS to instantiate:
Orthorectification is performed by the :class:`~orthority.ortho.Ortho` class, which requires a source image, DEM, :doc:`camera model <camera>` and world / ortho CRS to instantiate. The :meth:`~orthority.ortho.Ortho.process` method orthorectifies:

.. literalinclude:: ../../scripts/api_ortho.py
:language: python
Expand Down
9 changes: 9 additions & 0 deletions docs/getting_started/api/pan_sharp.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Pan sharpening
==============

The :class:`~orthority.pan_sharp.PanSharpen` class implements Gram-Schmidt pan sharpening. Panchromatic and multispectral images are required to instantiate. The :meth:`~orthority.pan_sharp.PanSharpen.process` method pan sharpens:

.. literalinclude:: ../../scripts/api_pan_sharp.py
:language: python

See the :meth:`~orthority.pan_sharp.PanSharpen.process` documentation for details on other configuration options.
Loading

0 comments on commit 5b4bfcf

Please sign in to comment.