A package that uses image georeferencing for monoplotting (single-image pixel-to-3D ray/surface intersection) and for projecting 3D coordinates into an image. Supports perspective imagery and orthophotos.
Project description
weitsicht
Python package to use the direct geo-reference information of images for mapping and projection.
Its designed to simplify the use and implementation of functions and classes needed all the way from image points to mapped
3d points or the other way around from 3d point to image points.
Additionally, it is easy to get information like mapped image footprints, center points or transform them to other coordinate systems. Single-image ray intersection with a ground/3D model is often called Monoplotting (in weitsicht this is what the image map_* methods like map_points / map_center_point / map_footprint do with a mapper).
There are classes for camera models, images, mapping functions and additional utils which simplify and abstract to a level where non-photogrammetry experts can work with it.
Currently, it is possible to use perspective and ortho-imagery and for mapping a horizontal plane, rasters (e.g. DSM) and meshes.
Capabilities:
- Monoplotting/Mapping, map the image’s center-point and footprint (image extend) or image point easily.
- Projection, get the pixel position of 3D coordinates.
- CRS, weitsicht handles coordinate system conversions (to some extend)
- Perspective Image and Camera, mathematic model of your digital camera and pose.
- Ortho imagery, use ortho imagery to map contant or convert 2D coordinates to 3D.
- Mapper Classes, several mapper classes can be used to map your pixel data: HorizontalPlane, Raster, Mesh
- ImageBatch, container class to perform tasks on multiple images. Find all images where coordinates are visible. Map for all images footprint and centerpoint.
- Meta-Data, use image’s meta-data (EXIF, XMP) to estimate camera model and image pose.
Table of Contents
- Installation
- Dependencies
- Documentation
- Brief History
- Goals
- Future Plans
- Contribution
- Discussion
- Package Structure
- Example Usage
- Notes on PyProj
- License
Installation
The source code is currently hosted on GitHub at: https://github.com/MartinW-S2M/weitsicht
PyPI
Binary installers for the latest released version are available at the [Python Package Index (PyPI)] https://pypi.org/project/weitsicht/
pip install weitsicht
From Source
In the weitsicht directory (same one where you found this file after cloning the git repo), execute:
pip install .
# include test dependencies
pip install .[test]
Tests use pytest and live in the tests folder. As well all scripts within examples are tested.
For testing Internet access has to be available as pyproj will download needed rasters (e.g EGM2008 earth gravity model)
Alternative its possible to tell pyproj to use local stored grids/data - see pyproj-datadir
Installation of 3rd-party dependencies
To provide a full simple workflow a package to read metadata is needed. see Dependencies
Dependencies
Python
weitsicht runs on Python 3.10+. weitsicht has been tested on Windows, Linux and MacOS, and probably also runs on other Unix-like platforms.
Packages
It relies only on well-developed packages
Additionally, to provide a workflow for drone imagery the metadata from images has to be extracted.
You can use Phil Harvey's exiftool together with PyExifTool.
Although long‑term maintenance of those packages is not clear, Phil Harvey's tool provides to date the most complete metadata
reader for most image formats, including raw camera files. In weitsicht provides an interface for different exiftool wrappers, but currently only a parser for tags from PyExifTool is implemented. A exiv2 parser would be very welcome as contributions.
Documentation
The current documentation is available at weitsicht.readthedocs.io There you will also find information about the mathematical background and definitions. ANy contributions are welcome for extending documentation.
Brief History
weitsicht was formerly part of WISDAM (Wildlife Imagery Survey – Detection and Mapping) (and its predecessor DugongDetector) but is now provided as its own python package. It is used as the photogrammetry/mapping core of WISDAMapp to map images, objects and project them back into images. This allows the users to assign groups, spatial metadata and find resights.
WISDAMapp (Wildlife Imagery Survey – Detection and Mapping) is a python GUI framework based on QT for the digitization and metadata enrichment of objects digitized in images and ortho-photos. Geo-referenced imagery can be used to map digitized objects to 3D or project them back into images for the purpose of grouping
The WISDAMapp repository can be found under http://www.github.com/WISDAMapp/
Currently WISDAMapp undergoes refactoring to switch from the old WISDAMcore to weitsicht
Goals
The intention of weitsicht is to provide the community an easy-to-use package to deal with geo-referenced imagery. No matter if environmental science, geomatic, GIS or drone community more and more imagery is available (mostly from drones/UAS) which can be used to perform mapping operations.
Many users can’t leverage their imagery beyond basic tasks without photogrammetry/SfM software; we aim to bridge that gap.
Future Plans
As the package is currently very basic, already a few topics are around which could be implemented:
- Extend image and camera model classes (For example, 360degree imagery)
- Extend Rotation class to other common notations.
- Import/Conversion of the results from photogrammetry / sfm packages.
- Improve mapping on mesh. (holes in the mesh are currently a problem)
- Provide ability to save derived geometries.
- Maybe switch coordinate class to use geopandas.
- Provide ability to use network assets for mapping (e.g. Cloud optimized geotiff)
Discussion
Use the discussion page for questions, support, and general discussion.
Contribution
Contributions are highly welcome to extend the package. All levels of contributions are welcome from extending the docs, examples, mathematical discussions, coding, test implementations, providing test samples. Please find more info in CONTRIBUTION.md
Package Structure
[!IMPORTANT] weitsicht uses pyproj and using the setting always_xy for all Transformers.
weitsicht was designed with flexibility and extensibility in mind. The library consists of a few classes, each with increasingly more features.
-
weitsicht.camerais the sub package for camera models (e.g. OpenCV camera model) It contains only the mathematical model used to transform 2D image coordinates to 3D coordinates in the camera system and backwards. This class mostly does not need to be called itself on a basic level but is used by the image class. New classes can be easily implemented or extended. -
weitsicht.imageis the subpackage which provides image classes. It is used to deal with the geo-reference information which states the image pose in 3D space. Main functions of the classes are:- project: Project 3D coordinates into image 2D space
- map_points: Map pixel points into 3D space using a provided mapper.
-
weitsicht.mappingis the subpackage which provides mapping classes. Currently, mapping bases on a horizontal plane (mappingPlane) and mapping based on raster (mappingRaster) using rasterio. Main functions of the classes are:- map_heights_from_coordinates: Get the height of coordinates.
- map_coordinates_from_rays: Get the intersection coordinates of a ray in 3D space
-
weitsicht.transformis the subpackage which provides transformation classes and functions- cooTransformer class: Transform points using pyproj. Also provides an option to create geojson dict
- utm_converter: Convert a coordinate to WGS84/utm and get crs class as well
- rotation class: Class dealing with Rotation matrices used in photogrammetry
[!NOTE] Some additional helper functions are needed to be used by WISDAM (e.g. the function to load classes by a dictionary)
Example Usage
Map Pixels to ground with height 0.0
import numpy as np
import pyproj
from pyproj import CRS
from weitsicht import (CameraOpenCVPerspective, ImagePerspective, MappingHorizontalPlane)
from weitsicht import Rotation
# To directly download the grids needed for coordinate transformation we enable the network capability of proj
pyproj.network.set_network_enabled(True)
# Construct Mapper
# We use the horizontal plane mapper in the CRS System WGS84 with EGM2008 heights
crs_mapper = CRS("EPSG:4326+3855")
mapper = MappingHorizontalPlane(plane_altitude=0.0, crs=crs_mapper)
# Camera Model
# The camera model's width and height is the image shape which was used during calibration,
# allowing the image class to use resampled images.
cam = CameraOpenCVPerspective(width=6000, height=4000, fx=2360, fy=2360)
# Image Pose
position = np.array([602013.0, 5340384.696, 100.0])
orientation = Rotation.from_opk_degree(omega=1.5, phi=5.6, kappa=65.0)
# Image Coordinate Reference System
crs = CRS("EPSG:25833+3855") # UTM Zone 33
image = ImagePerspective(width=6000, height=4000, mapper=mapper, camera=cam,
crs=crs, position=position, orientation=orientation)
# Map to image coordinates
result = image.map_points(np.array([[2000,300],[2300, 400]]))
if result.ok:
print("GSD of points: %f" % result.gsd)
print("Coordinates mapped", *result.coordinates)
Refer to documentation for more examples http://weitsicht.github.io/
Notes on PyProj
This packages heavily depends on pyproj CRS and Transformer/TransformerGroups.
[!IMPORTANT] weitsicht uses the setting always_xy for all Transformers. Except you are constructing your own transformation pipeline
The user must take care that all data is available for the Transformation needed (Pyproj - Datadir) or the network option is enabled (Pyproj - Network settings ).
pyproj.network.set_network_enabled(True)
All transformation are done by Transformer.from_crs().
Standard option is to allow only best transformations and an exception will be raised otherwise (Including ballpark transformations,
PyProj - Transformer).
To allow ballpark and allow also other than the best transformations, set:
weitsicht.allow_ballpark_transformations() # sets cfg._ballpark_transformation to True
# is the same as allow_ballpark_transformations(True), to disallow set to False
weitsicht.allow_non_best_transformations() # sets cfg._only_best_transformation to False
# is the same as allow_non_best_transformations(True), to disallow set to False
Licence
weitsicht is licensed under the Apache License, Version 2.0 (Apache-2.0).
See LICENSE for the full license text.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file weitsicht-0.0.2.tar.gz.
File metadata
- Download URL: weitsicht-0.0.2.tar.gz
- Upload date:
- Size: 121.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3a8e97542ef1f6983e781786a4ba323f434acda340798e8c4cdcb9ecccef3ef4
|
|
| MD5 |
1687c17126dce8e6a17940a27af2cfe0
|
|
| BLAKE2b-256 |
9a7d0b2eed8fe185fa8af9799fd8b9580ad110921f14ec66fa6fe185e208a603
|
Provenance
The following attestation bundles were made for weitsicht-0.0.2.tar.gz:
Publisher:
python-publish.yml on MartinW-S2M/weitsicht
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
weitsicht-0.0.2.tar.gz -
Subject digest:
3a8e97542ef1f6983e781786a4ba323f434acda340798e8c4cdcb9ecccef3ef4 - Sigstore transparency entry: 959081521
- Sigstore integration time:
-
Permalink:
MartinW-S2M/weitsicht@f9a511eea2294761d6818b59d9554c6114d7cc2a -
Branch / Tag:
refs/tags/v0.0.2 - Owner: https://github.com/MartinW-S2M
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@f9a511eea2294761d6818b59d9554c6114d7cc2a -
Trigger Event:
release
-
Statement type:
File details
Details for the file weitsicht-0.0.2-py3-none-any.whl.
File metadata
- Download URL: weitsicht-0.0.2-py3-none-any.whl
- Upload date:
- Size: 126.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a84bb953d6c41fdbf7fb726ec18851152087ae21614b4e32124a8cd52db3270a
|
|
| MD5 |
cadc9f226442fe2660a2aaedaf531712
|
|
| BLAKE2b-256 |
779a16057dd1e8a220d96c2e29794d4916bb0ce65f08c42f696a253395ddfd73
|
Provenance
The following attestation bundles were made for weitsicht-0.0.2-py3-none-any.whl:
Publisher:
python-publish.yml on MartinW-S2M/weitsicht
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
weitsicht-0.0.2-py3-none-any.whl -
Subject digest:
a84bb953d6c41fdbf7fb726ec18851152087ae21614b4e32124a8cd52db3270a - Sigstore transparency entry: 959081594
- Sigstore integration time:
-
Permalink:
MartinW-S2M/weitsicht@f9a511eea2294761d6818b59d9554c6114d7cc2a -
Branch / Tag:
refs/tags/v0.0.2 - Owner: https://github.com/MartinW-S2M
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@f9a511eea2294761d6818b59d9554c6114d7cc2a -
Trigger Event:
release
-
Statement type: