Fisheye image to a sky plane (fish2skyplane)

Written by Paul Bourke
November 2021

The following remaps a fisheye image such that distances on a plane perpendicular to the optical axis of the fisheye lens, are proportional to the distances on the image. Typically used for an upwards pointing fisheye lens where one want to measure the speed or area of features (such as clouds) at some height above the ground.

The key relationship is the expression for latitude (φ) above. It is mapping latitude linearly between 0 and φmax as r varies from 0 (center of image) to 1 (dotted line on image) corresponding to Rmax.

A free parameter is the maximum latitude value in the fisheye image one wants to transform. There is a trade-off between resolution and latitude range, the greater the desired latitude the larger the remapped image needs to be to retain the same resolution.
The example below uses a maximum latitude of 70 degrees.

Red lines define the fisheye circle.
Pink circle is the 70 degree circle.

Pixel width: 0.00183165 * H
Image width: 5.49495 * H

In order to make any real world measurements one needs to know the height of the plane on which those measurements apply. As shown above, the dimensions of each pixel in the image is known as a function of height, as well as the entire width of the image. This allows real world unit distance, speed and areas to be calculated of a tracked object. For example, in the above example if the cloud layer is 1km high then each pixel corresponds to 1.8m and the entire width of the image above is 5.5km.

The command line program to convert a single image has been created. The usage string is given below. Note that cropping to the maximum latitude circle is supported as well as options to rotate the view about the optical (up) axis of the fisheye lens.

Usage: fish2skyplane [options] imagefile
   -w n        sets the output image size, default: same as input fisheye
   -a n        sets antialiasing level, default: 2
   -s n        fisheye field of view (degrees), default: 180
   -c x y      fisheye center, default: center of image
   -r n        fisheye radius, default: half the fisheye image width
   -m n        maximum angle to represent, default: 60
   -z n        roll about the fisheye optical axis, default: 0.000000
   -l          enable cropping by maximum latitude, default: off
   -p n n n n  fourth order correction terms, default: no correction
   -o s        output filename, default: derived from input file
   -d          debug mode