CHDK/HOWTO: Calibrating the distance of the A620

=HOWTO: Distance calibration of the A620= Richard Lemieux, 2007-05-24

The purpose of distance calibration is to associate the right subject distance number to the lens position. On the A620, the lens position is known through the 'Canon distance number'.

The 'Canon distance number' is the number displayed in the manual focus mode and is remembered in 'Custom' mode if the focus was manual. When turning on the camera in 'Custom' mode, the camera returns the lens to the focus point where it was when the parameters were saved, if the 'manual focus' mode was then active.

Expect to be taking many measurements if you do this procedure.

PRELIMINARY
It appears that the 'Canon distance number' (s) relates to the movement of the lens focusing mechanism (x) as follows [1],

x = a0 + a1/s

x "(mm) Movement of the lens focusing mechanism" s "(0-65535) Canon distance number as returned by the A620" a0 = -a1/si si "Value of the Canon distance number when the lens focuses at Infinity" a1 "Parameter estimated through the calibration procedure"

Basic optics tells us the subject distance (D) for any position of the lens focusing mechanism (x). When 'x=0', the CCD is at the focus point of the lens and the lens is focused at infinity 'D=Inf'.

D = f + f^2/x

f "Focal length of the lens (7.3mm to 29.2mm on the A620)"

What we are going to do is to measure the distance between the lens rim and the subject when the lens is at zoom position 0 (7.3mm). Call this measure 'Dm'. Since 'Dm' is not 'D', I need to fill in the difference with an additional parameter 'd0' that is going to be different for each focal length of the lens.

The formula we are going to calibrate is the following,

Dm - d0 = f + (f^2/a1)/(1/s - 1/si)                                  (1)

Dm "(mm) Measured distance" s  "(0-65535) Number found on the OSD/misc display of the CHDK" d0 "(mm) Parameter to estimate" a1 "(mm) Parameter to estimate" si "   Parameter to estimate"

The last point is that we need to make sure that the A620 actually focuses on the subject when we take measurements of 'Dm' and 's'. We are going to depend on the autofocus of the camera. How the autofocus of the A620 actually works is a bit obscure. It is likely a contrast based system. My assumption is that the autofocus will set the focus on the subject if the subject if very contrasty and surrounded by low contrast objects. Ideally the subject should be isolated and above ground. The subject should look contrasty from the camera position at all zoom settings.

CALIBRATION
Calibration involves taking measurements and selecting the parameters that best fit the measurements. Doing it in reverse, I first look at how I will fit the parameters. I am going to need a plotting software and plot the following in log-log coordinates,

1. The measured data (Dm, s) 2. The value of Dm computed with formula (1) (Dm(s;d0,a1,si), s).

To plot the formula I need to select values of 'd0', 'a1', and 'si' to start with. It is safe to start with,

d0 = 0        Controls the low end of the plot (macro range). a1 = f^2      Controls the mid range of the plot (just a bit of control here). si = 2000     Controls the behavior at the largest distances (the most important parameter).

Then do the plot and evaluate how close the computed formula fits the data. Change the parameters and do it again until you are happy with the fit.

Now that you know what is needed, you are ready to start collecting the data. Just accumulate pairs of (Dm, s) using the CHDK for all focal lengths and for distances going from the closest to at most twice the hyperfocal distance. You may include data for far away subjects if you wish but be critical of the value of the data (was the autofocus capable of doing its job unambiguously?). Expect much fluctuation on 's' as the distance increases. Keep the measured data; don't make averages.

The hyperfocal distance number is found in the depth-of-field window on the CHDK software.

That's it for the calibration.

HOW TO USE THE RESULT
static float f_a[] = {7.300,8.460,9.565,10.835,12.565,14.926,17.342,21.709,29.200}; //           f_a  Array of focal lengths. static float si[]  = {1350, 1590, 1984, 3614, 4248, 8104, 10341, 11903, 21930}; static float fa1[] = {0.96458, 0.92003, 0.95259, 1.03059, 0.95736, 0.95754, 0.99251, 0.95281, 0.96006}; //            fa1 = f*f/a1 static float d0[]  = {-61.747, -61.747, -61.747, -86.446, -61.747, -61.747, -61.747, -61.747, -61.747};

//    z   Current zoom position. float f   = f_a[z]; float gcav = GetCurrentAvValue; float Av  = pow(2.,(double)(gcav/(2.0f*96.0f))); // Aperture number (2.8, 5.6 ...) float x   = (f*f/fa1[z])*(1.0f/s - 1.0f/si[z]); float Ar  = 0.915E-3f*Av;         // (mm) Radius of first ring of Airy figure (diffraction). float coc = 3E-3f;                // (mm) circle of confusion float xH  = Av*(Ar > coc ? Ar : coc);  // Use the largest between Ar and coc. float H   = f + f*f/xH;           // Hyperfocal distance float D1  = d0[z] + f + (1.0f - xH/f)*f*f/(x + xH); // Close end of DOF. float D   = d0[z] + f + f*f/x;                      // Subject distance. float D2  = d0[z] + f + (1.0f + xH/f)*f*f/(x - xH); // Far end of DOF.

REFERENCE
[1]  Richard Lemieux, A distance display for my Powershot A620.