Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature refine RPC & pan sharpen #15

Merged
merged 93 commits into from
Sep 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
93 commits
Select commit Hold shift + click to select a range
595ae20
add to dos
dugalh Jun 3, 2024
cf20b2b
update paths
dugalh Jun 12, 2024
6de8c90
typing fixes (tuple->list)
dugalh Jun 12, 2024
085734e
add rpc refinement backend
dugalh Jun 12, 2024
4d0c4b6
add functions for reading GCPs
dugalh Jun 12, 2024
c04bf12
changes and additions for GCP refinement of RPC models
dugalh Jun 12, 2024
6192c18
add RPC refinement method
dugalh Jun 12, 2024
e5208f4
note on RPC dict workaround
dugalh Jun 12, 2024
854cf43
add --grp-refine and --refine-method to oty rpc
dugalh Jun 12, 2024
4199064
remove redundant check on num gcps
dugalh Jun 17, 2024
99705cd
differentiate between fsspec and orthority OpenFile
dugalh Jun 24, 2024
89bc838
add pan sharpening module
dugalh Jul 21, 2024
fb29585
fix short form option duplicates
dugalh Jul 21, 2024
4296391
add tests for create_profile
dugalh Jul 22, 2024
b89b893
add create_profile
dugalh Jul 22, 2024
9439670
change to use utils.create_profile
dugalh Jul 22, 2024
9d086a4
round & clip before writing
dugalh Jul 23, 2024
44dd502
add convert_array_dtype()
dugalh Jul 23, 2024
a6f4ec9
move profile test to test_utils
dugalh Jul 23, 2024
6373a0b
write mask band and use utils.build_overviews()
dugalh Jul 24, 2024
667a8c2
move Ortho._build_overviews() to utils.build_overviews()
dugalh Jul 24, 2024
587222d
logging updates
dugalh Jul 24, 2024
4658ff7
add ruff
dugalh Jul 24, 2024
cb5cb79
utils.py -> common.py
dugalh Jul 24, 2024
e0860c1
refactor utils.py -> common.py
dugalh Jul 26, 2024
4d8236d
add pan index and re-solve weights w/o -ve bands
dugalh Jul 28, 2024
df7ddf2
- fix create_profile() for rgb+ jpeg source
dugalh Jul 31, 2024
7e7ff83
various minor updates
dugalh Jul 31, 2024
5c78f0a
dynamic_ncols() defaults to dynamic_ncols=True
dugalh Aug 1, 2024
a6e5281
vrt profile & masking updates
dugalh Aug 1, 2024
f4407c1
fix docstring
dugalh Aug 1, 2024
f7a9500
update & fix VRT profiles and update docstrings
dugalh Aug 6, 2024
12974db
simplify file callbacks & add pan-sharpen command
dugalh Aug 6, 2024
7168ff8
add GCP & pan sharp data and refactor downsampling
dugalh Aug 14, 2024
f7cebd8
pixel interleave on single band images for win image viewer support
dugalh Aug 14, 2024
a26cd0e
change --gcp-refine to work in front of an arg
dugalh Aug 14, 2024
3062b42
fix RPC adjustment for shift_drift method
dugalh Aug 15, 2024
2d2092a
add RPC refinement tests
dugalh Aug 15, 2024
9d9257e
use center pixel convention for all GCP formats
dugalh Aug 18, 2024
785153a
Error handling improvements
dugalh Aug 19, 2024
be8df04
Error checking and GCP IO updates:
dugalh Aug 19, 2024
f2d3bfd
Add --gcp-refine tests and tighten error checking
dugalh Aug 19, 2024
54b64a6
only recreate refined cameras
dugalh Aug 19, 2024
29827e0
add tests for refinement of RPCs
dugalh Aug 19, 2024
bfc8a13
report GCP tags/file exceptions
dugalh Aug 19, 2024
8e719da
add GCP fixture & modify create_profile() for general use
dugalh Aug 19, 2024
1c355a9
standardise center pixel coords for GCPs
dugalh Aug 19, 2024
c42c9db
validate_collection() improvements
dugalh Aug 19, 2024
583fdc0
add tests for validate_collection()
dugalh Aug 19, 2024
d449742
import PanSharpen
dugalh Aug 25, 2024
87b25e3
add pan & MS file fixtures
dugalh Aug 25, 2024
9719c0d
VRT profile and ms_indexes fixes
dugalh Aug 25, 2024
905cbd5
add PanSharpen tests
dugalh Aug 25, 2024
e2ae0b7
add thread pool shutdown
dugalh Aug 26, 2024
7e6ceb0
fix oty sharpen error reporting and --out-file
dugalh Aug 26, 2024
3743fac
add tests for oty sharpen
dugalh Aug 26, 2024
477bff8
make weight range >=0
dugalh Aug 28, 2024
150e118
check weight values and avoid GS coeff divide by 0
dugalh Aug 28, 2024
b938b31
high level weights tests
dugalh Aug 28, 2024
b1239f0
ms_indexes defaults to all non-alpha bands
dugalh Aug 28, 2024
93ed826
use OrthorityError for user data / argument issues
dugalh Aug 29, 2024
2586c40
changes to test masking with internal, nodata & alpha masks
dugalh Aug 29, 2024
af31e97
add vertical crs
dugalh Aug 29, 2024
2448fc2
update bounds & metadata:
dugalh Aug 29, 2024
a4aff02
update for reduced bounds
dugalh Aug 29, 2024
fdaa54f
fix read_oty_int_param() exception handling
dugalh Aug 29, 2024
fe894b1
add pan sharp images
dugalh Aug 29, 2024
160f32a
add gcps file
dugalh Aug 29, 2024
c667f47
fix typing annotations
dugalh Aug 29, 2024
fc81a43
fix & simplify test_process_ms_indexes()
dugalh Aug 29, 2024
d605743
remove repeated band
dugalh Aug 29, 2024
4fce7e0
py 3.8 compatibility:
dugalh Aug 30, 2024
6983612
gcp refinement fixes / updates:
dugalh Sep 2, 2024
d5ef7dd
add RpcRefine
dugalh Sep 2, 2024
064751b
change ref_kwargs -> fit_kwargs in RpcCameras.refine()
dugalh Sep 2, 2024
7f0c34a
add GCP file formats
dugalh Sep 4, 2024
6215e5c
add pan sharpening API docs
dugalh Sep 4, 2024
4fca655
use lists for image files
dugalh Sep 4, 2024
eceeffb
add RPC refinement docs
dugalh Sep 4, 2024
a37304d
suppress rasterio NotGeoreferencedWarning
dugalh Sep 4, 2024
5955585
update docstring for --export-param & --gcp-refine
dugalh Sep 4, 2024
15948f8
use MS dtype for pan sharpened image
dugalh Sep 6, 2024
d76c7f0
update docs for RPC refinement and pan sharpening:
dugalh Sep 7, 2024
25f9e78
re-organise the common text
dugalh Sep 7, 2024
82bc2c8
point github links at main branch
dugalh Sep 7, 2024
1a43609
updates for RPC refinement and pan sharpening
dugalh Sep 7, 2024
85a62ee
change tqdm.std -> tqdm.auto
dugalh Sep 7, 2024
e632096
improve test image downsampling
dugalh Sep 7, 2024
9e6d1eb
add oty sharpen to CLI section
dugalh Sep 7, 2024
43a330d
add debug log test
dugalh Sep 7, 2024
94cb0ac
revert to no log test
dugalh Sep 7, 2024
8b9d8fc
add fixture and test for -ve weights
dugalh Sep 7, 2024
821395e
shutdown before getting filename
dugalh Sep 7, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading