Thursday, November 21, 2024

Correcting Lens Distortion for Vintage Lenses

I love using vintage photographic lenses in my digital photography. Like all other lenses, they suffer from a number of imperfections which include lens distortion and transverse chromatic aberrations (TCA). In the age of digital processing, such effects can, however, be fixed in post processing. While flexible frameworks exist for this purpose, these usually include libraries for modern lenses but rarely for vintage glass.

Therefore, I determined the corrections for lens distortion and TCA for my vintage lenses, and I'm sharing the results, so that others may benefit from this work. (Note: one could also digitally correct for vignetting, but I consider vignetting as an artistic feature, so I did not spend the time and effort to implement this.) The corrections are determined for 27 vintage prime lenses on the full frame sensor of the Sony A7Rii.

  • Carl Zeiss Jena Flektogon 20mm f/4
  • Carl Zeiss Jena Flektogon 35mm f/2.4
  • Carl Zeiss Jena Pancolar 50mm f/1.8
  • Carl Zeiss Jena Biotar 58mm f/2
  • Carl Zeiss Jena Tessar 50mm f/2.8
  • Carl Zeiss Jena Sonnar 135mm f/3.5
  • Carl Zeiss Jena Triotar 135mm f/4 (version 2)
  • Meyer-Optik Görlitz Orestegon 29mm f/2.8
  • Meyer-Optik Görlitz Lydith 30mm f/3.5
  • Meyer-Optik Helioplan 40mm f/4.5
  • Meyer-Optik Görlitz Domiplan 50mm f/2.8
  • Meyer-Optik Görlitz Oreston 50mm f/1.8
  • Meyer-Optik Görlitz Orestor 100mm f/2.8
  • Meyer-Optik Görlitz Orestor 135mm f/2.8
  • Meyer-Optik Görlitz Orestegor 200mm f/4
  • Pentacon 50mm f/1.8
  • Schneider-Kreuznach Retina-Curtagon 28mm f/4
  • Schneider-Kreuznach Retina-Curtagon 35mm f/2.8
  • Schneider-Kreuznach Curtagon 35mm f/4
  • Schneider-Kreuznach Retina-Tele-Arton 85mm f/4
  • Schneider-Kreuznach Tele-Xenar 90mm f/3.5
  • Schneider-Kreuznach Retina-Tele-Xenar 135mm f/4
  • Steinheil München Auto-D-Quinaron 35mm f/2.8
  • Steinheil München Culminar 85mm f/2.8
  • Steinheil München Auto-D-Tele-Quinar 135mm f/2.8
  • Voigtländer Color-Ultron 50mm f/1.8
  • Beroflex 400mm f/6.3

The results are available for the "lensfun" library which can be used e.g. in software like Darktable, Rawtherapee, Digikam, Rawstudio, and others (but not in Lightroom). If you just want to go ahead and use the results, please scroll down to the instructions for "Download and Install". 
If you are interested in the underlying concepts and how these corrections are derived (and how you can easily derive your own corrections for other lenses), I give a brief overview with links to more detailed descriptions/instructions, plus figures comparing the distortions of different lenses.


Lens Distortion Model



There are two main types of lens distortion called "barrel" (left) and "pincushion" distortion (right), but also combinations of these two exist. In both cases, a true geometry (blue dashed lines) produces an image (red lines) with a distorted geometry.
While the following describes the distortion model used in lensfun, one should be aware that different models exist (e.g. Adobe uses a slightly different model). Based on the rotational symmetry of typical lenses, the distortion is parameterized only as a function of radius (the distance of a point from the center of the image). The radius is taken as the "normalized" radius, which is the radius of the largest circle that fits into the image, normalized to unity. For example, for a 24mm x 36mm full frame sensor, the circle with 12mm radius is being referred to as r = 1.
The assumption is that a point with true, undistorted radius ru ends up in the image at a different, distorted radius r which can be expressed as a polynomial in ru.
   r =  a ru4  + b ru+ c ru2 + v ru ,
or, after factoring out ru
   r = ru ( a ru3  + b ru+ c ru + v) .
If we define the circle with r = 1 as "undistorted" (so: ru = 1 = r), we get the normalization condition for the coefficients
     a + b + c + v = 1 ,
which translates into
   v = 1 - a - b - c .
Therefore, v can be eliminated and the final relation is
   r = ru ( a ru3  + b ru+ c ru + [1-a-b-c]) ,
with 3 parameters a, b, c.

Lensfun has implemented a lens correction function, based on this model. If for a given lens, the parameters a, b, c are known, lensfun can produce the corresponding distortion correction which can be used e.g. in Darktable (and the other codes mentioned above).

Software

The determination of these distortion parameters a, b, c sounds like a complex task. However, powerful software for this exists already as part of the panorama stitching software package Hugin. A nice and detailed description of the calibration procedure can be found here (including links at the bottom for specifics on the distortion, TCA, and vignetting corrections). In Hugin, there exist a "calibrate lens GUI" which would be the easiest way to determine the corrections. But this requires certain features in the calibration images which, for me, are not easy to find. Therefore, I am using Hugin's Python script lens_calibrate.py (on a Linux system) for which the installation and usage are described here.
This script uses Hugin to determine the TCA correction all by itself, but it needs a little manual input for the distortion correction.

Determination of the Distortion Parameters

A single image can be used for both the distortion and the TCA correction which should be taken at a distance of 8m or more. The former requires two straight lines, one at the very top of the image and another one about one third from the top, while the latter requires many sharp high-contrast edges (if possible black-white transitions). This is one of the images that I'm using (taken with the Meyer-Optik Oreston 2.8/100mm - which exhibits notable pincushion distortion).


For the TCA correction, there are obviously many black-white transitions - and for the distortion correction I am using the upper two horizontal lines. Following the instructions, I am adding a number of points along the two lines (as seen in the screen capture), from which Hugin can compute the distortion correction that makes these straight.


For the first lens it takes a little to understand the details of the procedure, but for subsequent lenses, it's actually pretty quick. And remember: you just have to do this once per lens - then you can correct the images from these lenses for the rest of your life.
After the correction is applied, the image from the Meyer-Optik Orestor 2.8/100mm shows straight, undistorted lines!


Here is a comparison of a 100% crop of the top left corner for the Carl Zeiss Jena Sonnar 3.5/135mm before (left) and after (right) the TCA correction is applied.



Notice how the green and purple edges are gone in the right image.

Comparing Lens Distortions

As discussed in the lens model description, the lens distortion modifies only the radial position of a light ray (i.e. the distance from the center). Therefore, the distortion can be displayed as the radial shift  (rd - r, in microns) as a function of radius, where the normalized radius in the above formulas has been converted to the radius on the full frame sensor (in millimeters). For the full frame sensor the radius of the corners is about 22mm (half of the diagonal).
A positive distortion that is increasing towards larger r, means that the corners are shifted outward, corresponding to pincushion distortion, while barrel distortion corresponds to negative values at larger r.

Distortion of 50-58mm Lenses


The Biotar and Domiplan have almost no distortion. The largest (barrel) distortion is seen for the Pentacon 1.8/50mm and the Meyer Oreston 1.8/50mm (since the Pentacon 50 is a renamed Meyer Oreston, it was expected that the two are identical).

Distortion of 85-100mm Lenses


The Culminar and the Tele-Xenar have almost no distortion while the Meyer Orestor 100mm has a strong pincushion distortion (and I'm very happy that this will be corrected for in the future, which is a strong improvement for this very sharp lens).

Distortion of 135-200mm Lenses


The old Zeiss Triotar (version 2, from 1952), and the Meyer Orestegor 200mm have almost zero distortion. The others have pincushion distortion - the Zeiss Sonnar is still pretty good.

Distortion of 20-35mm Lenses


The Zeiss Flektogons and the Schneider lenses have the least distortion. The Meyers and Steinheil have stronger barrel distortion.

Comparisons with Previous Results

I was curious about the robustness of this procedure, the stability of the results, and if these are reproducible. Would two people with two different different pieces of the same lens model and with two different images (and possibly two slightly different procedures) come up with consistent corrections for a lens type? Fortunately, for one of my lenses (the Zeiss Sonnar 3.5/135mm), lensfun already has a set of distortion corrections (but no TCA) available.
It is very satisfactory to see that the distortion corrections for the two are in perfect agreement, giving confidence that the results are reproducible. 

The TCA corrections will be posted later in another blog entry ... [please come back, and check here]

Download and Install

At some point my calibrations will be included in the lensfun library (I'm currently checking with the Lensfun people). Until then, the .xml file of my lens calibration data can be downloaded here:

          vintage-glass.xml   (version from Nov 20, 2024 - please check again for new versions)

On a Linux system, this file should be copied (using sudo) into the directory  /var/lib/lensfun-updates/version_1/ - from the command line:
    sudo cp vintage-glass.xml /var/lib/lensfun-updates/version_1/.

On Windows system it should be copied it into 
    C:\Program Files\darktable\share\lensfun\version_1

At start, Darktable will automatically find the file and read the new lens data. Please note, that these are made for a full frame sensor, so they will not show up when a APS-C or M43 camera was detected.

I hope this works for you! If not, please let me know.