Images Guide#
This guide explains how perspective images are handled in weitsicht and how that practical workflow
maps to the theory in Perspective Image.
Scope#
A perspective image in weitsicht is used as a geometric object that combines:
image pixel coordinates,
a camera model (intrinsics + distortion),
exterior orientation (camera pose),
optional mapper context for ray intersection.
If one of these parts is missing, some methods still run, but geo-accurate mapping results are limited.
The pixel → 3D intersection step for a single image is often referred to as Monoplotting (see Monoplotting).
Theory to Practice Mapping#
The theory page defines:
projection model (3D -> pixel),
inverse projection (pixel -> ray),
need for a surface constraint to get a unique 3D point.
In weitsicht, this maps to practical operations:
ImagePerspective.project(...): projects 3D points to image pixels (with optionalto_distortedbehavior).ImagePerspective.pixel_to_ray_vector(...): converts image pixels to ray directions.ImagePerspective.map_points(...): maps image pixels to 3D by ray intersection with a mapper.ImagePerspective.map_center_point(...): maps the principal point to 3D.ImagePerspective.map_footprint(...): maps corner/edge pixels to a 3D footprint.
Related camera-model conversion methods:
camera.distorted_to_undistorted(...)camera.undistorted_to_distorted(...)camera.pts_camara_crs_to_image_pixel(...)camera.pixel_image_to_camera_crs(...)
See:
Required Inputs#
For reliable georeferenced image usage, provide:
a valid camera model (currently OpenCV pinhole),
valid image size matching camera calibration assumptions,
valid EOR (position + orientation),
clear CRS relation between EOR and target coordinates.
How Camera, Geo-reference, and Mapper Are Assigned#
The perspective image object is ImagePerspective.
Constructor-based assignment:
from pyproj import CRS
from weitsicht.image.perspective import ImagePerspective
from weitsicht.transform.rotation import Rotation
image = ImagePerspective(
width=6000,
height=4000,
camera=camera_obj, # CameraBasePerspective implementation
crs=CRS("EPSG:31256+5778"), # perspective image CRS
position=[x, y, z], # EOR position in that CRS
orientation=Rotation(rotation_matrix=R), # EOR orientation
mapper=mapper_obj, # optional, can also be passed per call
)
Dictionary-based assignment:
image = ImagePerspective.from_dict(
{
"width": 6000,
"height": 4000,
"position": [x, y, z],
"orientation_matrix": R.tolist(),
"camera": camera_obj.param_dict,
"crs": CRS("EPSG:31256+5778").to_wkt(),
},
mapper=mapper_obj,
)
Geo-reference validity in code:
image.is_geo_referencedisTruewhen position, orientation, and camera are set.Mapping methods also need a mapper (assigned on the image or passed to the call).
Practical Workflow#
Typical usage order:
Load camera model parameters.
Build/load perspective image object with camera + EOR.
Validate coordinate conventions (camera CRS and pixel CRS).
Project a few known points and inspect residuals.
Convert image pixels to rays when needed.
Intersect rays with a mapper for 3D coordinates.
Use returned masks/issues to filter invalid outputs.
Method Summary (Actual API)#
project(coordinates, crs_s=None, transformer=None, to_distorted=True): 3D -> pixel projection.pixel_to_ray_vector(pixel_pos, is_undistorted=False): image pixel -> ray vector.map_points(points_image, mapper=None, transformer=None, is_undistorted=False): pixel -> 3D coordinates through mapper intersection.map_center_point(mapper=None, transformer=None): principal point -> 3D.map_footprint(points_per_edge=0, mapper=None, transformer=None): image footprint -> 3D polygon points.image_points_inside(point_image_coordinates): checks if undistorted image points are inside the valid distortion border.
Distortion and Valid Pixels#
If distortion is enabled, not every undistorted pixel is valid.
weitsicht uses a precomputed distortion border in the camera model to mask invalid undistorted pixels.
For details, see Cameras & Distortion Borders.
Common Pitfalls#
Using EOR from another software without converting convention.
Mixing image size and calibration size without updating intrinsics.
Ignoring validity masks from projection/mapping results.
Assuming one CRS for all components when 3D point CRS and perspective image CRS differ.