Sunday, 16 January 2011

Depth of field calculator

This year I'm going to start talking about one of my passions: Photography. And for starting, here you can get one of my last applications: Thundax Depth of Field Calculator. With this Delphi win32 front-end application you'll be able to calculate the Depth of field (the portion of a scene that appears sharp in the image) measurements needed in photography. You need to select the CoC (Circles of Confusion) in microns from the sidebar (there is a little sheet with the normal values for different types of cameras), the focal length from the choices, and the lens aperture from the choices. Enter the subject distance in meters from the lens and the calculated values are returned for various other designations of subject distance as well as the near limit of acuity, far limit of acuity, and the total depth of field, all in both meters and feet, accurate and rounded. The calculations are based on the very well known on-line DoF javascript calculator.

In my application you can see the difference of using different apertures (F numbers) while taking the photo. In the example you can see that the distance is the same, but the DoF grows. The aperture is getting smaller and smaller, and the shutter speed is getting longer to compensate. The distance and aperture both play a big role in depth of field. You you want to play with it, for example: for a short depth of field (blurry background) get close and use a lower f-stop. And for a long depth of field (clear all the way through) get farther away and use a higher f-stop. The following example will help you to understand better the DoF:
Picture from: Photo Basics.
The different calculations are the following ones:
procedure TDoF.Calc(Sender: TObject);
var
    focal: integer;
    aperture: double;
    CoC: double;
    Hyperfocal: double;
    distance: double;
    NearF, FarF, doftotal: double;
begin
    distance := StrToFloat(Edit2.Text) * 1000 * 0.3048;
    focal := getFocal(ComboBox1.Text);
    aperture := getAperture(ComboBox2.Text);
    CoC := StrToFloat(Edit1.Text);
    photovalues.Values['Subject distance (inches)'] := FloatToStr(StrToFloat(Edit2.Text) * 12) + ' in';
    photovalues.Values['Subject distance (meters)'] := FloatToStr(StrToFloat(Edit2.Text) * 0.3048) + ' m';
    photovalues.Values['Subject distance (millimeters)'] := FloatToStr(StrToFloat(Edit2.Text) * 0.3048 * 1000) + ' mm';
    Hyperfocal := 0;
    if (aperture * CoC) > 0 then
        Hyperfocal := Sqr(focal) / (aperture * CoC);
    photovalues.Values['Hyperfocal distance for this lens/aperture combination (meters)'] := FloatToStr(Hyperfocal) + ' m';
    photovalues.Values['Hyperfocal rounded distance for this lens/aperture combination (meters)'] := FormatFloat(f, Hyperfocal) + ' m';
    photovalues.Values['Hyperfocal distance for this lens/aperture combination (ft)'] := FloatToStr(Hyperfocal * feet) + ' ft';
    photovalues.Values['Hyperfocal rounded distance for this lens/aperture combination (ft)'] := FormatFloat(f, Round(Hyperfocal * feet)) + ' ft';
    NearF := ((Hyperfocal * 1000 * distance) / ((Hyperfocal * 1000) + (distance - focal))) / 1000;
    photovalues.Values['Near limit of acceptable sharpness (meters)'] := FloatToStr(NearF) + ' m';
    photovalues.Values['Rounded near limit of acceptable sharpness (meters)'] := FormatFloat(f, Round(NearF)) + ' m';
    photovalues.Values['Near limit of acceptable sharpness (ft)'] := FloatToStr(NearF * feet) + ' ft';
    photovalues.Values['Rounded near limit of acceptable sharpness (ft)'] := FormatFloat(f, Round(NearF * feet)) + ' ft';
    FarF := ((Hyperfocal * 1000 * distance) / ((Hyperfocal * 1000) - (distance - focal)) / 1000);
    if FarF < 0 then
    begin
        photovalues.Values['Far limit of acceptable sharpness (meters)'] := 'Infinity';
        photovalues.Values['Rounded far limit of acceptable sharpness (meters)'] := 'Infinity';
        photovalues.Values['Far limit of acceptable sharpness (ft)'] := 'Infinity';
        photovalues.Values['Rounded far limit of acceptable sharpness (ft)'] := 'Infinity';
    end
    else
    begin
        photovalues.Values['Far limit of acceptable sharpness (meters)'] := FloatToStr(FarF) + ' m';
        photovalues.Values['Rounded far limit of acceptable sharpness (meters)'] := FormatFloat(f, Round(FarF)) + ' m';
        photovalues.Values['Far limit of acceptable sharpness (ft)'] := FloatToStr(FarF * feet) + ' ft';
        photovalues.Values['Rounded far limit of acceptable sharpness (ft)'] := FormatFloat(f, Round(FarF * feet)) + ' ft';
    end;
    doftotal := Round(FarF - NearF);
    if doftotal < 0 then
    begin
        photovalues.Values['Total depth of field (meters)'] := 'Infinity';
        photovalues.Values['Total rounded depth of field (meters)'] := 'Infinity';
        photovalues.Values['Total depth of field (ft)'] := 'Infinity';
        photovalues.Values['Total rounded depth of field (ft)'] := 'Infinity';
    end
    else if (doftotal >= 0) and (doftotal < 0.001) then
    begin
        photovalues.Values['Total depth of field (meters)'] := '> 1 mm';
        photovalues.Values['Total rounded depth of field (meters)'] := '> 1 mm';
        photovalues.Values['Total depth of field (ft)'] := '> 0.0393 in';
        photovalues.Values['Total rounded depth of field (ft)'] := '> 0.0393 in';
    end
    else
    begin
        photovalues.Values['Total depth of field (meters)'] := FloatToStr(doftotal) + ' m';
        photovalues.Values['Total rounded depth of field (meters)'] := FormatFloat(f, Round(doftotal)) + ' m';
        photovalues.Values['Total depth of field (ft)'] := FloatToStr(doftotal * feet) + ' ft';
        photovalues.Values['Total rounded depth of field (ft)'] := FormatFloat(f, Round(doftotal * feet)) + ' ft';
    end;
end;

Tell me if it's useful to you and if you need any other calculations.
PS: The program is free for non-commercial use.


Related links:

2 comments:

  1. Really very good blog.This blog provides good information about Depth of field calculator.Can we use this calculator to find out the distance between two postcodes.

    ReplyDelete
  2. Hi,

    This bespoke tool is thought to calculate the DoF for a given object. Thank you for your comments.
    Jordi

    ReplyDelete