## Lens Correction and DistortionWritten by Paul BourkeApril 2002
The following describes how to transform a standard lens distorted image into what one would get with a perfect perspective projection (pin-hole camera). Alternatively it can be used to turn a perspective projection into what one would get with a lens. To illustrate the type of distortion involved consider a reference grid, with a 35mm lens it would look something line the image on the left, a traditional perspective projection would look like the image on the right.
The equation that corrects (approximately) for the curvature of
an idealised lens is below. For many lens projections a
Note that this is a radial distortion correction. The matching reverse transform that turns a perspective image into one with lens curvature is, to a first approximation, as follows.
In practice if one is correcting a lens distorted image then one actually wants to use the reverse transform. This is because one doesn't normally transform the source pixels to the destination image but rather one wants to find the corresponding pixel in the source image for each pixel in the destination image. Note that in the above expression it is assumed one converts the image to a normalised (-1 to 1) coordinate system in both axes.
"Proof of concept code" is given here: map.c As with all image processing/transformation processes one must perform antialiasing. A simple supersampling scheme is used in the above code, a better more efficient approach would be to include bicubic interpolation. Adding distortion
The effect of adding lens distortion to the image is shown below for a perspective projection of a Menger sponge by Angelo Pesce. The image on the left is the original from PovRay, the image on the right is the lens affected version. (distort.c)
F. Devernay and O. Faugeras.
H. Farid and A.C. Popescu
R. Swaminatha and S.K. Nayer
G. Taubin
## Non-linear Lens DistortionWith an example using OpenGL (lens.c, lens.h)
Written by Paul Bourke
The following illustrates a method of forming arbitrary non linear lens distortions. It is straightforward to apply this technique to any image or 3D rendering, examples will be given here for a few mathematical distortion functions but the approach can use any function, the effects are limited only by your imagination. At the end an OpenGL application is given that implements the technique in real-time (given suitable OpenGL hardware and texture memory).
Some parts of the image are compressed and other parts inflated, the inflated regions need a higher input image resolution in order to be represented without aliasing effects. The above transformations cope with the input and output images being different sizes, normally the input image needs to be much larger than the output image. To minimise aliasing the input image should be larger by a factor equal to the maximum slope of the distorting function. There are no noticeable artefacts in these example because the input image was 10 times larger than the output image. ## OpenGL
This OpenGL example implements the distortion functions above
and distorts a grid and a model of a pulsar. It can readily be modified
to distort any geometry. The guts of the algorithm can be found in the
HandleDisplay() function. It renders the geometry as normal, then copies the
resulting image and uses it as a texture that is applied to a regular
grid. The texture coordinates of this grid are formed to give the
appropriate distortion.
(lens.c, lens.h)
The left button rotates the camera around the model, the middle button
rolls the camera, the right button brings up a few menus for changing the
model and the distortion type. It should be quite easy for you to add
your own geometry and to experiment with other distortion functions. Improvements and exercises for the reader
An improvement would be to render the texture at a larger size so that there is more resolution at those parts of the distorted image that are inflated. The note above on image resolution is clearly observed in this OpenGL implementation. Some OpenGL implementations will support non square power of 2 textures in which case the restrictions on the window size can be removed. Many implementations also support non square power of 2 textures if mipmapping is enabled. If you'd like to try some other interesting distortion functions then experiment with the following.
The first is similar to the fisheye lens people used to attach to the window of their ute. The second is similar to the wave-like distorting mirrors found at carnival shows.
One thing you might want to consider is using glCopyTexSubImage2D instead of doing a slow glReadPixels. Using the first allows me to play UT smoothly with distortion enabled. glReadPixels is a very slow operation on consumer level boards. And until there is a "rendering to texture" extension for OpenGL taking the texture directly from the back buffer is the fastest way - and it even is optimized.
## Computer Generated Camera Projections and Lens DistortionWritten by Paul BourkeSeptember 1992 See also Projection types in PovRay
Most users of 3D modelling and rendering software are familiar with parallel and perspective projections when they generate wire frame, hiddenline, simple shaded or highly realistic rendered images. It is possible to mathematically describe many other projections some of which may not be available, feasible, or even possible with conventional photographic equipment. Some of these techniques will be illustrated and discussed here using as an example a computer based model of Adolf Loos' Karntner bar. The 3D model was created by Matiu Carr in 1992 at the University of Auckland's School of Architecture, using Radiance.
The following is a 180 degree (vertically) by 360 degree (horizontally) angular fisheye. It unwraps a strip around the projection sphere onto a rectangular area on the image plane. The distance from the centre of the image is proportional to the angle from the viewing direction vector. Figure: Fisheye 180
90 degree (vertically) by 180 degree (horizontally) angular fisheye. Figure: Fisheye 90
A panoramic view is another method of creating a 360 degree view, it removes vertical bending but introduces other forms of distortion. This is created by using a virtual camera that has a 90 degree vertical field of view and a 2 degree horizontal field of view. The virtual camera is rotated about the vertical axis in 2 degree steps, the resulting 180 image strips are pasted together to form the following image. Figure: Panoramic 360 Some other "real" examples
180 degree panoramic view of Auckland Harbour.
360 by 180 degree panoramic view created by a camera developed at Monash University, Melbourne. |