CHDK adds a RAW shooting option to many point and shoot cameras, including Canon PowerShot SX710HS. As the camera does not apply lens correction automatically for RAWs, one has to fix lens distortion when developing the RAWs. Lensfun is the go-to place for FOSS lens correction, however it did not have lens correction data for the SX710HS. So I’ve decided to calibrate the lens myself.
The Lensfun tutorial for lens calibration is quite cumbersome. It directs you go out and shoot some buildings with straight lines, and then manually track those lines in Hugin and extract the distortion parameters. Well, after searching a bit, I came up with what I think is a better workflow.
I’ve started by creating in Inkscape (using the Cartesian grid tool) and printing a page with regularly spaced horizontal lines. I’ve printed it on an A3 paper, but in hindsight A4 would have worked just the same and is more available. I’ve placed the paper on the floor, added some simple lightning and and placed a paperclip in the middle just to make focusing easier.
Next I’ve took several shoots at each focal length, having the printed lines parallel to the long side of the image. To make sure I’m covering the entire zoom range consistently, I’ve used my set_zoom script. I’ve taken calibration shoots in 0 (minimal focal lenght), 5, 10, 20, … ,100, 110 and 111 (maximal focal length) zoom steps. After taking all the shots, I’ve copied the DNGs (CHDK saved RAWs as DNGs) from the camera, and used exiftool to sort them into directories by focal length:
$ exiftool '-directory<${FocalLength;}' *.DNG
As we will use Hugin, for the calibration and Hugin does not support DNGs, we have to convert them to TIFFs.
The -t 0 is used to remove the orientation info from the TIFFs. As I shoot the pictures with camera pointing straight down, that info is many times incorrect and messes up the calibration in Hugin.
Load each set of TIFFs of a given focal length into Hugin Lens Calibration GUI. Make sure the focal length and focal length multiplier are correct (for some reason Hugin was off by 0.01-0.02 sometimes), and use the “Find lines” button to automatically detect straight lines. Next optimize the radial distortion parameters. Those a, b and c parameters are the numbers Lensfun needs.
The next step is to create a Lensfun profile for the camera. The basic blocks are the <camera> tag and the <lens> tag. Both are mandatory, even thought the camera has a fixed lens. For each focal length we calibrated the lens for, we add a <distortion> tag, modifiying the focal and the a, b and c parameters according to the values from the calibration GUI.
The lens’ model name follows the Lensfun convention for CHDK. However, it makes auto-detection of the lens to fail in many application such as Darktable. You can workaround it by copying exactly the model name from the <camera> tag. The xml file itself should go in ~/.local/share/lensfun.
The two pictures in the beginning of the post show some examples of uncorrected and corrected photos using the newly acquired calibration data.
CHDK supports programmatically setting the zoom level on the camera. However, the exact range for the zoom and apparently the translation between the zoom level in CHDK to actual focal length is camera dependent.
In order to figure out the exact range for the zoom and the relation between the numerical zoom steps and the focal length, I’ve used the following Lua script to get the current zoom setting and set it to a certain value. I’ve also configured the display of the camera to show the exact focal length at all times.
-- Guy Rutenberg 2018-08-10
--
--[[
@title Get and Set Zoom
@chdk_version 1.3
@param z Zoom level
@default z 0
--]]
z_old = get_zoom()
print("Current zoom "..z_old)
print("Zooming to "..z)
set_zoom(z)
Next, I’ve set the zoom to multiple value, and plotted it against the actual focal length. The results are shown in the graph above.
The range for the zoom is 0 to 111, which matches focal length of 4.5 to 135mm. The change is pretty linear in two section: 0 to about 85 and again from 85 up to 111.