I collect here the specifications behind edition 3 of the distance computation functions I use on my A620. The C functions as well as the installation instructions are to be found in file rf_3.c.
The purpose of this software is to compute calibrated distance values for,
d The distance from the lens to the current focus point. c The close end of the depth-of-field range. f The far end of the depth-of-field range. H The hyperfocal distance. s The separation to use to make stereo pictures.
The functions return text to be displayed on the CHDK.
The history of this project is,
Edition 1. Data acquisition and distance calibration done by manual curve fitting. Edition 2. Internal model of the focusing model, formula, and additional data acquisition. Edition 3. Review of specifications; addition of stereo separation; a more compact program.
Warning. Those specifications are provided as a reference and are not meant to be easily digestible. The specification format is a loose combination of basic formal logic and the Lamport approach to writing specifications.
Basic Optical Formulas xD: "Relation between the lens displacement and the focus distance." &1. x "(mm) Distance from the focal point of the lens to the image of the subject. Displacement of the lens from the focal point of the lens." [Definition, f1.jpg] &2. D "(mm) Distance from the front of the lens to the object." [Definition, f1.jpg] &3. f "(mm) Focal length of the lens." [Definition] &4. H "(mm) Height of a point of the subject." [Definition, f1.jpg] &5. y "(mm) Height of the point on the CCD that correspond to the point H" &6. H/D = y/(x+f) [Similar triangles] &7. H/f = y/x [Similar triangles] &8. D = f + f^2/x [6, 7, solving for D] &9. x = f^2/(D-f) [6, 7, solving for x]
D1D2D_f_coc: "Relation between the depth of field, the subject distance, the focal length, and the circle of confusion." &1. A "(mm) Diameter of the aperture of the lens." [Definition, Optics, f2.fig] &2. Av "() Aperture number; f number." [Definition, Optics, cameras] &3. Av = f/A "Typical values of Av are 2.8, 5.6, 8, ..." [1, 2, Definition] &4. coc "(mm) Diameter of the circle of confusion" [Definition, Photography, f2.fig] &5. D1 "(mm) Close end of the depth-of-field range" [Definition, Photography] &6. D2 "(mm) Far end of the depth-of-field range" [Definition, Photography] &7. x1 "(mm) Position of the image of a subject at the close distance D1" {Definition, Photography, f2.fig] &8. x2 "(mm) Position of the image of a subject at the far distance D2" [Definition, Photography] &9. (A/2)/(f + x1) = (coc/2)/(x1 - x) [Similar triangles, xD:1] &10. (A/2)/(f + x2) = (coc/2)/(x - x2) [Similar triangles, xD:1] &11. x1 = (A*x + f*coc)/(A - coc) [9] &12. xH = f*coc/A [definition] &13. xH = Av*coc [12, 3] &14. x1 = (x + xH)/(1 - coc/A) [13, 9, lemma1:4] &15. x2 = (x - xH)/(1 + coc/A) [10, lemma2:5] &16. x1 = (x + xH)/(1 - xH/f) [14,12] &17. x2 = (x - xH)/(1 + xH/f) [15,12] lemma1: &1. A x1 - A x = coc f + coc x1 [D1D2D_f_coc:9] &2. (A - coc) x1 = coc f + A x [1] &3. x1 = (coc f/A + x)/(1 - coc/A) [2] &4. x1 = (xH + x)/(1 - coc/A) [3, D1D2D_f_coc:13] lemma2: &1. A x - A x2 = coc f + coc x2 [D1D2D_f_coc:10] &2. A x - coc f = coc x2 + A x2 [1] &3. A x - coc f = (A + coc) x2 [2] &4. x2 = -(coc f/A - x)/(1 + coc/A) [3] &5. x2 = -(xH - x)/(1 + coc/A) [4, D1D2D_f_coc:13] H: "Hyperfocal distance" &1. x = xH [Hypothesis, D1D2D_f_coc:13] &2. x2 = 0 [1, D1D2D_f_coc:17] &3. D2 = Inf [2, xD:8] &4. x1 = 2*xH/(1-xH/f) [1, D1D2D_f_coc:16] &5. D1 = f + f^2*(1-xH/f)/(2*xH) [4, xD:8] &6. D1 = f - f/2 + f^2/(2*xH) [5] &7. D1 = (f + f^2/xH)/2 [6] &8. D = f + f^2/xH [1, xD:8] &9. D1 = D/2 [8] &10. H = "Hyperfocal distance" [Definition] &11. H = D = f + f^2/xH [Definition] &12. x = Av*coc => D = H = f + f^2/(Av*coc) && D1 = H/2 && D2 = Inf [D1D2D_f_coc:13]
a620_calibration: &1. s "Distance number returned by the camera" [ExifTool:DistanceUpper, CHDK:distance] &2. a0, a1 "Parameters estimated through calibration procedure" [www.cooptel.qc.ca/~rlemieu/rf2_a620_calibration.html] &3. x = a0 + a1/s [1, 2, xD:1]
stereo_background: "Lateral displacement between stereo shots. Background" &1. d "Lateral displacement between the two stereo shots" [f3.jpg] &2. y1 "Half the displacement of the close point of the depth-of-field range" [f3.jpg] &3. y2 "Half the displacement of the far point of the depth-of-field range" [f3.jpg] &4. y1/(f+x) = (d/2)/D1 [Similar triangles, f3.fig] &5. y2/(f+x) = (d/2)/D2 [Similar triangles, f3.fig] &6. (y1 - y2)/2 = ((f+x)*d/2)*(1/D1 - 1/D2) [4,5] &7. 7.15 "(mm) CCD width" [Powershot A620] &8. (1/30) "() Fraction of CCD width allowed for 2*(y1-y2)" [Maximum disparity, microfunguy] &9. 2*(y1 - y2)/7.15 = (1/30) [7,8] &10. d = ((1/30) * 7.15/(f+x))/(1/D1 - 1/D2) [6,9] optimal_stereo_d_1: "Computation of the optimal stereo distance: D2 > 0" &1. (1/D1 - 1/D2) = (D2 - D1)/(D1*D2) [algebra] &2. D2 - D1 = f^2 * (1/x2 - 1/x1) [xD:8] &3. D1 * D2 = (f + f^2/x1) * (f + f^2/x2) [xD:8] &4. D1 * D2 = f^2 * (1 + (f*(x1 + x2) + f^2)/(x1*x2)) [3] &5. x1 - x2 = (2*xH*x/f + 2*xH)/(1 - xH^2/f^2) [D1D2D_f_coc:{16,17}] &6. x1 + x2 = (2*x + 2*xH^2/f)/(1 - xH^2/f^2) [D1D2D_f_coc:{16,17}] &7. x1 * x2 = (x^2 - xH^2)/(1 - xH^2/f^2) [D1D2D_f_coc:{16,17}] &8. D2 - D1 = f^2 * (x1 - x2)/(x1*x2) [2] &9. D1 * D2 = f^2 * (x1*x2 + f*(x1 + x2) + f^2)/(x1*x2)[4] &10. (D2 - D1)/(D1*D2) = (x1 - x2)/(x1*x2 + f*(x1 + x2) + f^2) [8,9] &11. (1/D1 - 1/D2) = 2*xH*(x/f + 1)/((x^2 - xH^2) + f*2*xH(x/xH + xH/f) + f^2 * (1 - xH^2/f^2)) &12. (1/D1 - 1/D2) = 2*xH*(x/f + 1)/(x^2 + 2*f*x + f^2) &13. (1/D1 - 1/D2) = 2*xH*(x/f + 1)/(x + f)^2 &14. (1/D1 - 1/D2) = 2*(xH/f)*(x + f)/(x + f)^2 &15. (1/D1 - 1/D2) = 2*(xH/f)/(x + f) &16. (1/D1 - 1/D2) = 2/(x + f)/(xH/f) &17. (1/D1 - 1/D2) = 2/(x*f/xH + f^2/xH) &18. (1/D1 - 1/D2) = 2*xH/((x + f)*f) & &C1 x = xH [hypothesis] &C2 1/D1 - 1/D2 = 2/(f + f^2/xH) [18, C1] &C3 1/D1 - 1/D2 = 2/H [C2, H:{1,11}] &C x = xH => 1/D1 - 1/D2 = 2/H [C{1,2,3}] &19. d = ((1/30) * 7.15/(f + x)*f*(x + f)/(2*xH) [18, stereo_background:10] &20. d = (1/30) * 7.15 * f/(2*xH) [19] &21. d = (1/30) * 7.15 * f/(2*Av*coc) [20, D1D2D_f_coc:13] &22. d = (1/30) * (7.15/f) * (H - f)/2 [21] &23. | & f = 7.3mm [Hypothesis] & Av = 2.8 [Hypothesis] & coc = 3 microns [Hypothesis] & H = 6.35 m. [H:12] & d = 10.4 cm [22] & "f=7.3, Av=2.8, H = f + f^2/(Av*coc), d = (1/30) * (7.15/f) * (H - f)/2" [Octave] & 10.5cm "Camera result" [A620, rf_3.c, CHDK] &24. | & f = 29.2mm [Hypothesis] & Av = 4.1 [Hypothesis] & coc = 3 microns [Hypothesis] & H = 6.35 m. [H:12] & d = 19.6 cm [22] & "f=20.2, Av=4.1, H = f + f^2/(Av*coc), d = (1/30) * (7.15/f) * (H - f)/2" [Octave] & 21cm "Camera result" [A620, rf_3.c, CHDK] &25. "The Av returned by the A620 may differ slightly from the nominal value used here" [A620, CHDK PropertyCase 39, 23,24] optimal_stereo_d_2: "Computation of the optimal stereo distance: D2 < 0" &1. "D2 < 0 with D1 > 0 means that objects from D1 to Infinity are in focus" &2. substitute 1/D1 for (1/D1 - 1/D2) in stereo_background:10 [1] &3. d = (1/30) * 7.15*D1/f [2, x > -xH, and xH much smaller than f] lemma3: &1. x1 = (x + xH)/(1 - xH/f) [D1D2D_f_coc:16] &2. x2 = (x - xH)/(1 + xH/f) [D1D2D_f_coc:17] &4. x1 = (x + xH)*(1 + xH/f)/(1 - xH^2/f^2) [1] &5. x2 = (x - xH)*(1 - xH/f)/(1 - xH^2/f^2) [2] &6. (x + xH)*(1 + xH/f) = x + x*xH/f + xH + xH^2/f [4] &7. (x - xH)*(1 - xH/f) = x - x*xH/f - xH + xH^2/f [5] &8. x1 - x2 = (2*x*xH/f + 2*xH)/(1 - xH^2/f^2) [4,5,6,7] &9. x1 - x2 = 2*xH*(x/f + 1)/(1 - xH^2/f^2) [8] &10. x1 + x2 = (2*x + 2*xH^2/f)/(1 - xH^2/f^2) [4,5,6,7] &11. x1 + x2 = 2*xH(x/xH + xH/f)/(1 - xH^2/f^2) [10]
summary: &1. x = a0 + a1/s [a620_calibration:3] &2. xH = Av*coc [D1D2D_f_coc:13] &3. D1 = f + (1 - xH/f)*f^2/(x + xH) [xD:8, D1D2D_f_coc:16] &4. D = f + f^2/x [xD:8] &5. D2 = f + (1 + xH/f)*f^2/(x - xH) [xD:8, D1D2D_f_coc:17] &6. H = f + f^2/(Av*coc) [H:12] &7. d = (1/30) * 7.15 * f/(2*xH) [optimal_stereo_d_1:20] &8. d = (1/30) * 7.15*D1/f [optimal_stereo_d_2:3]
Richard Lemieux. Distance calibration of the A620.
rf_3.c The latest edition of the program.
E_A610: "Extending the calibraton to an A610" &1. f_a = {7.300,8.460,9.565,10.835,12.565,14.926,17.342,21.709,29.200} &2, a620/si = {1350, 1590, 1984, 3614, 4248, 8104, 10341, 11903, 21930} &3. a610/si[0] = {1957, 2184, 2701, 5800, 6335, 14612, 17860, 17232, 32010} &4. delta(x) = f^2*delta(1/s) &5. &1. "In octave" &2. si_a620=[1350, 1590, 1984, 3614, 4248, 8104, 10341, 11903, 21930]; &3. f_a = [7.300,8.460,9.565,10.835,12.565,14.926,17.342,21.709,29.200]; &4. dx1 "Difference in the position of the stopper!" &5. dx1 = 7.3^2*(1/1350 - 1/1957) &6. si_a610=floor(0.5 + 1 ./ ((1 ./ si_a620) - (dx1 ./ (f_a.^2)))) &7. si_a610 = {1957, 2184, 2701, 5800, 6335, 14612, 17860, 17232, 32010}