Overview
Algorithm
alproj is a simple python package for geo-rectification of alpine landscape photographs.
alproj has 3 steps for geo-rectification of a landscape photograph.
Setting Ground Control Points (GCPs) in a target photograph, using a simulated landscape image rendered with Digital Surface Model and airborne photographs.

Heuristic estimation of camera parameters including the camera angle, field of view, and lens distortions (shooting point of the photograph is required).

Reverse perspective projection of the target photograph on Digital Surface Model, with estimated camera parameters, using OpenGL.

Now, every pixel in the photograph has its geographic coordinates!

You can export the results as a GeoTIFF using the built-in to_geotiff function:
from alproj.project import to_geotiff
to_geotiff(
georectified, # Result of reverse_proj()
"ortholike.tif",
resolution=1.0, # Pixel resolution in meters
crs="EPSG:6690", # Coordinate Reference System
bands=["R", "G", "B"], # Bands to export
interpolate=True # Fill small gaps
)
You can open the created GeoTIFF file with GIS software such as QGIS and ArcGIS.

The Camera Model
alproj uses a camera model that is almost same as the OpenCV’s one, however, the distortion coefficients are a little bit modified.
OpenCV
alproj
I added a1 and a2 to express inequal aspect ratios of image pixels.
Equidistant Fisheye Model
For wide-angle monitoring cameras, alproj also supports an equidistant fisheye projection model. Set "model": "fisheye" in the camera parameters to use it. The fisheye model projects 3D points using:
$$ r = f \cdot \theta_d, \quad f = w / \mathrm{fov_{rad}} $$
where $\theta$ is the angle between the ray and the optical axis, and $\theta_d$ is the distorted angle:
$$ \theta_d = \theta (1 + k_1 \theta^2 + k_2 \theta^4 + k_3 \theta^6 + k_4 \theta^8) $$
The radial distortion uses 4 coefficients (k1–k4) operating in angle space. Additionally, the model supports aspect ratio correction (a1, a2) and tangential distortion (p1, p2) in image space — 8 parameters in total, compared to the pinhole model’s 14. It typically provides better accuracy for cameras with significant barrel distortion.
Note: The fisheye simulation (sim_image, reverse_proj) internally renders a wide rectilinear image and remaps it. Because rectilinear projection cannot exceed ~140° FOV, fisheye simulation works best for FOV ≤ 120°. Higher FOV values will trigger a warning and edge regions may use interpolated values. The point projection (project) has no such limitation.
Future applications in alpine ecology, geology, and glaciology
Drawing vegetation maps from landscape photographs taken by hikers.
Analysing snow melting with webcams attached at mountain huts.
Estimating the area of glaciers in the past from historical photographs of glaciers.