Distortion correction profile for Tamron 18-300mm f/3.5-6.3 Di III-A VC VXD Lens for Sony E

I’ve created a distortion correction profile for Tamron 18-300mm f/3.5-6.3 Di III-A VC VXD Lens for Sony E to be used with Lensfun.

<lensdatabase>
    <lens>
        <maker>Tamron</maker>
        <model>E 18-300mm F3.5-6.3 B061</model>
        <mount>Sony E</mount>
        <cropfactor>1.534</cropfactor>
        <calibration>
            <!-- Taken with Sony A6000 -->
            <distortion model="ptlens" focal="18.0" a="0.02805" b="-0.10668" c="0.06382" />
            <distortion model="ptlens" focal="27.0" a="0.01683" b="-0.04455" c="0.03014" />
            <distortion model="ptlens" focal="38.0" a="-0.01212" b="0.06048" c="-0.07478" />
            <distortion model="ptlens" focal="53.0" a="-0.00924" b="0.05064" c="-0.06029" />
            <distortion model="ptlens" focal="60.0" a="-0.00417" b="0.0245" c="-0.02118" />
            <distortion model="ptlens" focal="86.0" a="-0.00333" b="0.02128" c="-0.02027" />
            <distortion model="ptlens" focal="100.0" a="0.01239" b="-0.03935" c="0.05252" />
            <distortion model="ptlens" focal="129.0" a="-0.00494" b="0.02116" c="-0.01855" />
            <distortion model="ptlens" focal="158.0" a="-0.00539" b="0.01724" c="-0.00662" />
            <distortion model="ptlens" focal="196.0" a="-0.02316" b="0.09408" c="-0.11133" />
            <distortion model="ptlens" focal="241.0" a="0.00321" b="-0.01004" c="0.01943" />
            <distortion model="ptlens" focal="277.0" a="0.01905" b="-0.04979" c="0.03944" />
            <distortion model="ptlens" focal="300.0" a="0.03685" b="-0.12817" c="0.15026" />
        </calibration>
    </lens>
</lensdatabase>

You can use it by saving the above file as lensfun.xml under ~/.local/share/lensfun/.

Resizing Huge Panoramas for Google Photos

Google Photos imposes a 100 megapixel limit on uploaded photos. This may sound like a lot, as even the very high-end Sony Alpha a7R III has “only” 48MP sensor, but in reality when you shoot panoramas and stitch them yourself, you can quickly get there, and hit the 100MP limit. When you try to upload your huge panorama to Google Photos, you will get a

A photo or video was skipped

error.

To solve it, you need to resize your image and make it smaller. This can be done automatically using ImageMagick’s convert:

$ convert -resize "100000000@>" panorama-in.jpg panorama-out.jpg

This will resize the panorama-in.jpg to at most 100MB, and save it as panorama-out.jpg. The > makes sure we will only down-size larger photos.

By default under Debian, ImageMagick comes with a very strict `policy.xml` controling the resources it can use. Practically, it means that unless you change those limits, you’ll encounter resource limit errors such as:

convert-im6.q16: width or height exceeds limit `panorama-in.jpg' @ error/cache.c/OpenPixelCache/3802.

To solve it you will need to edit /etc/ImageMagick-6/policy.xml and increase the limit for memory, width, height and area. For example:

  <policy domain="resource" name="memory" value="8GiB"/>
  <policy domain="resource" name="width" value="128KB"/>
  <policy domain="resource" name="height" value="128KB"/>
  <policy domain="resource" name="area" value="8GB"/>

Lens calibration workflow for Canon PowerShot SX710HS

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.

find -name "*.DNG" | xargs --verbose -P6 -I{} dcraw -t 0 -T {}

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.

Hugin Lens Calibration GUI, after line detection and optimization.
Hugin Lens Calibration GUI, after line detection and optimization.

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.

<lensdatabase version="1">
    <camera>
        <maker>Canon</maker>
        <model>Canon PowerShot SX710 HS</model>
        <model lang="en">PowerShot SX710 HS</model>
        <mount>canonSX710HS</mount>
        <cropfactor>5.6</cropfactor>
    </camera>
    <lens>
        <maker>Canon</maker>
        <model>Canon PowerShot SX710 HS & compatibles, with CHDK's DNG</model>
        <model lang="en">fixed lens, with CHDK's DNG</model>
        <model lang="de">festes Objektiv, mit CHDK-DNG</model>
        <mount>canonSX710HS</mount>
        <cropfactor>5.6</cropfactor>
        <aspect-ratio>4:3</aspect-ratio>
        <calibration>
            <distortion model="ptlens" focal="4.5" a="0.03396" b="-0.11175" c="-0.01779" />
            <distortion model="ptlens" focal="5.5" a="0.03289" b="-0.11253" c="0.02444" />
            <distortion model="ptlens" focal="6.6" a="0.02218" b="-0.08388" c="0.03521" />
            <distortion model="ptlens" focal="9.5" a="0.01211" b="-0.04143" c="0.02055" />
            <distortion model="ptlens" focal="13.5" a="-0.0022" b="0.00264" c="-0.00558" />
            <distortion model="ptlens" focal="18.2" a="-0.00212" b="0.00441" c="-0.00378" />
            <distortion model="ptlens" focal="23.4" a="0.00328" b="-0.01242" c="0.01298" />
            <distortion model="ptlens" focal="29.1" a="-0.00036" b="-0.00082" c="0.00209" />
            <distortion model="ptlens" focal="36.2" a="0.00129" b="-0.00626" c="0.00705" />
            <distortion model="ptlens" focal="46.3" a="0.00715" b="-0.02588" c="0.0244" />
            <distortion model="ptlens" focal="46.3" a="0.00715" b="-0.02588" c="0.0244" />
            <distortion model="ptlens" focal="62.9" a="0.00067" b="-0.00852" c="0.01085" />
            <distortion model="ptlens" focal="92.0" a="-0.00306" b="0.00016" c="-0.00374" />
            <distortion model="ptlens" focal="128.7" a="-0.0037" b="0.00365" c="-0.00582" />
            <distortion model="ptlens" focal="135.0" a="0.00333" b="-0.02616" c="0.03388" />
        </calibration>
    </lens>
</lensdatabase>

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’s set_zoom range for Canon PowerShot SX710HS

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.

Zoom to focal length, Canon PowerShot SX710HS

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.