Skip to content

Instantly share code, notes, and snippets.

@pigeonhill
Last active February 10, 2020 21:52
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pigeonhill/fdbc6e2fbeed1206afcc47d69cee9591 to your computer and use it in GitHub Desktop.
Save pigeonhill/fdbc6e2fbeed1206afcc47d69cee9591 to your computer and use it in GitHub Desktop.
DoF Bar
-- DoF Bar
-- Version 1.672
-- Released Feb 2020
-- Garry George - http://photography.grayheron.net/
--[[
DOF Bar User Guide
DoF Bar is principally targeted at those that wish to obtain 'tack sharp' images from infinity to a near-field point of interest, eg landscape and cityscape photographers; either from a single image or through focus bracketing.
It can, however, also be useful to those who simply wish to know more about their depth of field (DoF).
It goes without saying that DoF Bar only works in a Canon EOS camera with Magic Lantern, in Live View and with lenses that report focus distance, focal length and aperture. DoF Bar checks for this and will only show itself if it is able to so do.
When bracketing, DoF Bar is best being used at the wider end, say 50mm or wider. Although it can be used with longer lenses, be warned: focus bracketing can become tiresome at long focal lengths ;-)
For example, using the Rule of 10, a 100mm lens at F/10, using an infinity defocus blur of the FL in microns, will have a hyperfocal distance (H) of about 10m = FL/10. If we now bring this down from 100 microns to 10 microns, H corresponding moves to 100m, ie 10 x the H at 100 microns.
The number of focus brackets to cover from, say, 10m (X) to infinity will be 5, using a 10 micron criterion as the overlap, ie H/2X = 100/(2*10).
Whereas, if we wished to cover from 1m to infinity, we would need 50 brackets (=100/(2*1)), that is an additional 45 to cover from 10m to 1m!!! This emphasizes the non-linearity of focus when infinity distances are involved.
As a further illustration of the above, let’s assume we relax things and use an ‘OK’ CoC of 30 microns with our 100m lens, ie H becomes one third of the H required to achieve a 10 micron CoC, ie 100m/3 = 33.3m. If we still wish to cover a focus range of 1m to infinity (at a CoC of 30 microns), the number of brackets will ‘reduce’ to about 17, ie H/2X = 33.3/(2*1).
In other words, don’t try and focus bracket, too far into the near field, with long lenses ;-)
The current point of focus is shown by ML on the ML bottom bar. DoF Bar explicitly sets metric units in ML. DoF Bar will switch off ML shown DoFs, as DoF Bar shows this info, and more.
DoF Bar menu appears under the ML Focus menu. All DoF Bar menu states are remembered at camera close, so you don't have to keep entering your settings once you have arrived at your preferred configuration.
DoF Bar uses the ML set (total) Circle of Confusion (CoC), ie the total (sic) blur criterion at the hyperfocal. The total_blur being calculated from SQRT(lens_defocus_blur^2 + diffraction_blur^2). With diffraction blur linearly varying with aperture alone, ie a lens at F/8 has twice the diffraction blur of one at F/4.
If ML diffraction aware is set to off, the ML (total) CoC is, obviously, the lens defocus blur, alone. If ML diffraction aware is on, then the (lens defocus) hyperfocal (H) is calculated by ML after diffraction is accounted for, ie lens_defocus_blur = SQRT(total_blur^2 - diffraction_blur^2).
If diffraction is too high, DoF Bar will alert you by showing the DoFs as a red “X?X”
So, be warned: according to your ML set CoC, apertures much beyond, say, F/16, on a full frame (less than this on a crop sensor camera), mean you begin to lose DoF because of diffraction.
Because of diffraction, many photographers try and capture images around F/8 to F/11, as pushing things towards F/16, whilst resulting in larger DoF, will introduce loss of image quality, eg total blur and degrade the lens’s achievable lp/mm, because of factors related to lens design. For example see: https://www.cambridgeincolour.com/tutorials/lens-quality-mtf-resolution.htm
You can switch DoF Bar on and off, ie hide it in LV, via the script's menu.
NOTE: If DoF Bar 'disappears', for whatever reason, then simply carry out a half-shutter press to return DoF Bar to the LV screen.
The DoF Bar bar is segregated into three sub-areas, each with different scaling; in order to maximise the info presented in the bar.
The left hand (white) sub-bar covers distances from zero (assumed to be the camera's sensor plane) to a minimum distance that the user sets (this does not have to be the actual lens minimum). This min is only a visual aid and is user set in the script’s menu. Note that a minimum less than 4 * focal_length is not allowed.
Hint: one way to use this user-controlled feature is to move your lens to the macro end until the near depth of field doesn't change, ie focus is at its minimum. You may consider this to be your minimum and set this in the menu. Alternatively set it to a number you can remember, such as 500mm. It’s your choice.
The middle (green) sub-bar covers distances from your set minimum to the (diffraction aware) ML calculated hyperfocal distance (H). Thus, if the minimum focus is set to 500mm, the green bar will go from 500mm to H. Note H can be read from the ML DoF Focus menu.
The right hand sub-bar (with three zones, white/black/white) covers distances from white=[H to 2H], black=[2H to 3H], white=[3H to 4H]. This right hand zone is used when ‘infinity focusing’, ie beyond the ML calculated H.
Note that infinity blurs go in proportion to the focus distance beyond H. Thus if focused at x*H, your infinity blur will be the defocus blur at H (as calculated by ML) divided by x. For example, at 3H the infinity blur is (defocus_blur@H)/3.
As defocus blurs less than twice the sensor pitch are rather meaningless, as you need at least two pixels to resolve a line pair; DoF Blur uses H/4 as a pragmatic limit; knowing that we are using DoF Bar with Canon EOS sensors.
In Pro bracketing mode (see below) DoF Bar will only allow you to set infinity blurs between H and 4H. For example, on a 5D3, twice the sensor pitch is about 13 microns; and most will set the ML set (full frame) blur to, say, 30 microns, as this is recognised as an OK criterion to use for 'normal' viewing/scrutiny of an image. The smallest (DoF Bar allowed) infinity blur in this case is thus 30/4, which is about 8 microns, ie slightly less than, but close to, the 'sensible' (two pixel) sensor limit.
The script also limits Pro Mode bracketing to lenses of 50mm or less. You can do non-Pro Mode bracketing at any focal length.
There are two Pro Mode options. One shows the number of brackets from your current position to H. The other shows the defocus blur of the last image taken at the near DoF (white) and the infinity defocus blur (magenta), once again of the last image taken.
Of course, for web-based digital viewing, blurs can be larger than for close scrutiny print viewing. But, unless you know the final presentation mode and what blur you wish to achieve, it is best to seek infinity blurs between 30 to, say, 12 on a full frame, and, say, 20 to, say, 8 on a crop sensor. DoF Bar, of course, helps you by indicating the sweet spot.
When bracketing, the left hand of the bar will always be the lesser of the current near DoF and the near DoF of the last image taken. If DoF mode is selected, the right hand will be at H if both the current and last far DoFs are greater than H; or at the greatest of last far DoF and current far DoF. If Hyperfocal mode selected, the right hand will always be at H if the current far DoF is less than H.
These two dynamic modes become useful as you focus towards the macro end, so the advice is have the Dynamic Bar switched on.
There are three 'info areas’ above the bar.
The left hand one always shows the current near DoF distance and the defocus blur (all blurs are in brackets), as reported by ML. Note this is diffraction aware.
Each reported blur (always in microns) is prefixed by a letter: f = focus blur; d = diffraction blur; t = total blur; the addition of an i = the blur at infinity, ie associated with the far DoF when focusing beyond the hyperfocal.
The right hand info area shows the current (ML reported) far DoF distance, if the focus distance is less than H. If the focus is greater than H, this info area shows three blurs (in microns): the first is the current infinity (defocus) blur, ie at the current focus distance; the middle blur is the diffraction blur (which only changes when you change aperture); the third blur shows the root mean square of the other two, ie the total blur at infinity.
Additional information is provided by the colour of blur reporting. Green means that the focus is less than 4H and that the defocus blur is more than the diffraction blur. Yellow means that the focus is still less than 4H but now diffraction blur is more than defocus blur. Red means that the focus is beyond 4H, ie beyond pro mode being active.
The third info area (in the middle of the bar) only appears in Pro Mode and shows the infinity blur that is currently set, ie an image taken between H and 4H. Remember, the infinity blur is set by taking an image between H and 4H. This info remains visible, as a reminder, even when focus is less than H.
The infinity blur will then remain in force UNTIL the lens state changes, ie aperture or focal length, or you change the ML set total CoC. If you change lens state, you will need to take another image between H and 4*H to reset the infinity blur that is ‘in play’.
Or, put another way, if you wish to reset the infinity blur at anytime, all you need do is change lens state and (sic) take an image between H and 4H.
In its non-bracketing mode, the Focus Bar shows the three main focusing fiducial markers/semi-dots below the bar. Red is the focus point and the left and right white semi-dots show the near and far DoFs.
As soon as you take your first image (anywhere), if bracketing mode is set to off (script’s menu), all you will see are these dots mirrored on top of the bar and these will remain mirrored as you refocus.
However, if you are in bracketing mode, once an image has been captured, the upper dots will now be (and remain) positioned at the last captured image’s points of interest, ie near-DoF, focus point and far DoF.
The current focus’s white, near or far, DoF semi-dots will turn blue when you have opened a 'focus gap' between your last image taken and the current focus.
You can now use these top and bottom dots to inform your focus bracketing, ie refocus until the lower far DoF is just greater that the upper near DoF (of the last image), ie white and not blue. Thus, in (non Pro) bracketing mode, you can focus bracket in any direction at anytime (assuming you have taken one image anywhere).
If you are focusing at/beyond the Canon/ML indicated infinity, the lower dots will turn black as you are in an over focusing state; and you should consider backing off your focus. Note if you lens has a calibrated ‘hard stop’, you may wish to accept the lens-controlled infinity.
When the far DoF is at infinity you will see a white circle with a black centre.
Due to the coarseness of the Canon distance reporting, you may not always be able to position your focus to exactly where you want: do the best you can – always focusing longer rather than shorter when shooting landscapes.
If you are in Pro Mode and bracketing (set in the script’s menu) two additional upper and lower (magenta) semi-dots will appear. The upper magenta semi-dot shows the near DoF of the first captured image you took between H and 4H after camera switch or after a lens state change.
The infinity blur for that image is used to calculate the (infinity blur based) near DoF. The lower magenta semi-dot shows the (infinity blur based) far DoF at the current focus, once again using the infinity blur criterion established when you captured your image between H and 4H.
As you refocus, to achieve the perfect focus bracket, the lower magenta semi-dot will change from magenta to blue when you have opened up a focus gap.
Note: in Pro mode you should/can only focus bracket from far to near. That is start, and take an image, between H and 4H.
The infinity blur criterion will remain fixed until you change the focal length, aperture or the ML set hyperfocal by changing the CoC in ML; and (sic) take a new image between H and 4H.
Thus you can focus bracket at image sequences less than H, BUT, in Pro mode you must have taken your first image of a bracket set (after camera switch on or after a lens state change) between H and less than 4H, and, of course, focus stack from far to near.
Having set your infinity blur (by taking an image between H and 4H), all you need to do on subsequent focus brackets is to ensure the two magenta dots (top = last near DoF and bottom = current far DoF, both based on the infinity defocus blur) are as close together as possible (that is as close as the Canon focus reporting allows); and both are magenta, ie if the lower turns blue you need to refocus or accept where you are if the current far (white) DoF marker is still white, meaning that you are between the ML set/calculated blur and the infinity blur DoFs.
If all this appear confusing, one way to look at the above is to recognize that DoF Bar allows you to use two hyperfocals. The white dots showing the near and far DoFs associated with a hyperfocal calculated by ML; whereas the magenta dots show the DoFs associated with a hyperfocal based on the distance you were at when you took your image between H and 4H.
If both magenta and white far DoFs of the current focus are blue, you will have a (real) focus gap that needs fixing.
You can keep using the magenta dots for additional bracketing (far to near). As soon as you do a lens state change and take an image between H and 4H, you will establish a new infinity blur criterion.
Remember, in Pro mode the middle Info area reminds you of the blurs that are being used to calculate the white and magenta (H based) DoF dots, ie ML set (at the OK focus quality level) and your currently active infinity (defocus) blur (higher quality than using H)
Don’t forget: If you change the focal length, the aperture or the ML set CoC; the DoF Bar will reset to its ‘camera on’ state, eg the upper dots will disappear, until you take another image. Plus, in Pro mode, the infinity blur based info will be reset and you will need to take an image between H and 4H to establish a new (Pro mode) infinity blur.
Finally, you can use DoF Bar as an armchair visualization tool. For instance, to inform you how DoF changes as you adjust aperture, eg by looking at the changing DoFs until they are at their maximum and suit your needs.
Caveat emptor: remember that the equations that ML and DoF Bar use are good approximations away from the macro end, based on mathematically simplifying the lens. In other words, don't use DoF Bar with a macro lens!
(C) Garry George 2020
]]
require("config")
y_zero = 50 -- in screen units. Used to ensure below ML top bar (use y and x zeros to reposition bar)
x_zero = 40 -- bar gap on the left and right
bar_width = display.width - x_zero*2
bar_depth = 8
dot_size = 6
bar_margin = 10
font_UI = FONT.MED_LARGE -- Note this may be changed by the user to, say, FONT.LARGE
bar_pos = y_zero + font_UI.height + 2 + dot_size/2
lower_dots_pos = bar_pos + bar_depth
infinity = 655000 -- trap ML reported infinity
dof_infinity = 999999
H = lens.hyperfocal -- from ML, eg diffraction aware according to ML settings
last_H = lens.hyperfocal
h = lens.hyperfocal -- set to H for now, used for infinity focusing
c_limit = 4*H -- [H to 2H][2h to 3H][3H-4H]
current_n_dof = lens.dof_near
current_fp = lens.focus_distance
if current_fp > infinity then current_n_dof = H else current_n_dof = lens.dof_near end
current_f_dof = lens.dof_far
current_ap = camera.aperture.value
current_fl = lens.focal_length
last_ap = camera.aperture.value
last_fl = current_fl
last_n_dof = current_n_dof
last_f_dof = current_f_dof
last_fp = current_n_dof
h_based_ndof = current_n_dof
h_based_fdof = current_f_dof
last_h_based_ndof = h_based_ndof
focus_min = 0 -- in mm - note that this is purely visual, ie doesn't need to match lens actual focus min
-- Change the following 3 to suit your needs: must add up to 100/100. Note if using dynamic mode these are handled by the script
a_per = 10/100 -- covers 0 to min focus as set in menu
b_per = 60/100 -- covers min focus to hyperfocal
c_per = 30/100 -- covers hyperfocal to c_limit
b_c_logic = H
erased = false
card_count = dryos.shooting_card.file_number
text_1 = ""
text_2 = ""
text_9 = ""
ok_to_use = false
CON = "ON"
COFF = "OFF"
dynamic_choices = {"OFF", "Hyperfocal", "DoF"}
pro_choices = {"OFF", "Blurs", "Brackets to H", "Show Focus"}
image_taken = false
image_taken_past_H = false
something_changed = false -- used to detect changes that effect H and used to reset h
current_infinity_blur = 0
infinity_blur = 0
current_CoC = lens.focal_length*lens.focal_length/(camera.aperture.value*(lens.hyperfocal-2*lens.focal_length))
last_current_fp = current_fp
screen_refresh = true
diff_blur = 0
current_total_blur = 0
infinity_total = 0
-- ensure ML is set up correctly for DoF Bar
menu.set("DOF Settings", "DOF info in LiveView", "OFF")
menu.set("Lens Info Prefs", "Focus Distance Units", "mm/cm")
function my_display(text,time,x_pos,y_pos)
text = string.rep("\n",y_pos)..string.rep(" ",x_pos)..text
display.notify_box(text,time*1000)
end
if current_n_dof ~= 0 and current_f_dof ~= 0 and current_fp ~= 0 then
ok_to_use = true
else
my_display("Sorry can't use DoF Bar",10,20,3)
return
end
function myround(num,dp)
-- num = a number, dp = decimal places required to show
-- returns number as a string
if dp == 0 then
num = tostring(math.floor(num))
else
num = tostring(math.floor(num)).."."..string.sub(tostring(math.floor(num*10^dp)),-dp,-1)
end
return num
end
function bar_x_pos(x_pos)
if x_pos < focus_min then
x_pos = x_zero + a_per*bar_width*x_pos/focus_min
elseif x_pos <= b_c_logic then
x_pos = x_zero + a_per*bar_width + b_per*bar_width*(x_pos-focus_min)/(b_c_logic-focus_min)
elseif x_pos > b_c_logic then
x_pos = x_zero + a_per*bar_width + b_per*bar_width + c_per*bar_width*(x_pos-b_c_logic)/(c_limit-b_c_logic)
end
if x_pos > (bar_width + x_zero) then x_pos = bar_width + x_zero end
if x_pos <= x_zero then x_pos = x_zero end
return x_pos
end
function property.HALF_SHUTTER:handler(value)
screen_refresh = true
end
function show_focus_bar()
if camera.gui.menu or camera.gui.play or camera.gui.qr or menu.visible then
if not erased then
display.clear()
erased = true
last_current_fp = 0
end
else
if lv.overlays == 2 and not menu.visible then -- in ML overlay screen so OK to display/update DoF Bar
-- draw DoF Bar background
erased = false
display.rect(0 , y_zero, display.width, lower_dots_pos + dot_size/2 + bar_margin - (y_zero - bar_margin),COLOR.TRANSPARENT, COLOR.TRANSPARENT)
display.rect(x_zero - bar_margin , y_zero - bar_margin , bar_width + 2*bar_margin, lower_dots_pos + dot_size/2 + bar_margin - (y_zero - bar_margin),COLOR.TRANSPARENT_BLACK, COLOR.TRANSPARENT_BLACK)
c_limit = 4*H
focus_min = DoF_Bar_Menu.submenu["Min focus"].value
if DoF_Bar_Menu.submenu["Dynamic Bar"].value == "OFF" then
a_per = 10/100
b_per = 60/100
c_per = 30/100
else
if current_f_dof < H then
a_per = 0
b_per = 100/100
c_per = 0
if not image_taken then
last_f_dof = current_f_dof
last_n_dof = current_n_dof
end
if last_n_dof < current_n_dof then focus_min = last_n_dof else focus_min = current_n_dof end
if DoF_Bar_Menu.submenu["Dynamic Bar"].value == "Hyperfocal" then
b_c_logic = H
elseif DoF_Bar_Menu.submenu["Dynamic Bar"].value == "DoF" then
if current_f_dof < H and last_f_dof < H then
if current_f_dof < last_f_dof then b_c_logic = last_f_dof else b_c_logic = current_f_dof end
else
b_c_logic = H
end
end
else
a_per = 10/100
b_per = 60/100
c_per = 30/100
b_c_logic = H
end
end
-- update DoF info displays
diff_blur = 2.44*camera.aperture.value*0.550
current_total_blur = math.sqrt(current_CoC*current_CoC+diff_blur*diff_blur/(1000*1000))
if lens.hyperfocal < dof_infinity then
if current_fp >= H then -- display infinity blur info in microns
if menu.get("DOF Settings", "DOF formula") == "Simple" then
text_2 = current_CoC*lens.hyperfocal/lens.focus_distance
current_infinity_blur = text_2
text_2 = "(if"..tostring(math.floor(1000*text_2+0.5))..")"
if current_fp > infinity then
text_2 = "if0"
display.print(text_2, display.width - x_zero - font_UI:width(text_2), y_zero-5, font_UI, COLOR.RED, COLOR.TRANSPARENT_BLACK)
elseif current_fp > 4*H then
display.print(text_2, display.width - x_zero - font_UI:width(text_2), y_zero-5, font_UI, COLOR.RED, COLOR.TRANSPARENT_BLACK)
else
display.print(text_2, display.width - x_zero - font_UI:width(text_2), y_zero-5, font_UI, COLOR.GREEN1, COLOR.TRANSPARENT_BLACK)
end
else -- add additional blur info to account for diffraction aware
current_infinity_blur = current_CoC*lens.hyperfocal/lens.focus_distance
infinity_total = math.floor(math.sqrt(1000*1000*current_infinity_blur*current_infinity_blur + diff_blur*diff_blur))
text_2 = "(if"..tostring(math.floor(1000*current_infinity_blur+0.5)).."/d"..tostring(math.floor(diff_blur)).."/t"..tostring(math.floor(infinity_total))..")"
if current_fp > infinity then
text_2 = "(if0".."/d"..tostring(math.floor(diff_blur)).."/t"..tostring(math.floor(infinity_total))..")"
display.print(text_2, display.width - x_zero - font_UI:width(text_2), y_zero-5, font_UI, COLOR.RED, COLOR.TRANSPARENT_BLACK)
elseif current_fp < 4*H and diff_blur > 1000*current_infinity_blur then
display.print(text_2, display.width - x_zero - font_UI:width(text_2), y_zero-5, font_UI, COLOR.YELLOW, COLOR.TRANSPARENT_BLACK)
elseif current_fp > 4*H then
display.print(text_2, display.width - x_zero - font_UI:width(text_2), y_zero-5, font_UI, COLOR.RED, COLOR.TRANSPARENT_BLACK)
else
display.print(text_2, display.width - x_zero - font_UI:width(text_2), y_zero-5, font_UI, COLOR.GREEN1, COLOR.TRANSPARENT_BLACK)
end
end
else -- display far DoF distance
if current_f_dof < 1000 then
text_2 = myround(current_f_dof/10, 0).."cm"
elseif current_f_dof < 10000 then
text_2 = myround(current_f_dof/1000,2).."m"
else
text_2 = myround(current_f_dof/1000,0).."m"
end
if menu.get("DOF Settings", "DOF formula") == "Simple" then
text_2 = "(t"..tostring(math.floor(current_CoC*1000+0.5)).."):"..text_2
else
text_2 = "(t"..tostring(math.floor(current_total_blur*1000+0.5)).."):"..text_2
end
if current_CoC >= diff_blur/1000 then
display.print(text_2, display.width - x_zero - font_UI:width(text_2), y_zero-5, font_UI, COLOR.WHITE, COLOR.TRANSPARENT_BLACK)
else
display.print(text_2, display.width - x_zero - font_UI:width(text_2), y_zero-5, font_UI, COLOR.YELLOW, COLOR.TRANSPARENT_BLACK)
end
end
else
text_2 = "X?X"
display.print(text_2, display.width - x_zero - font_UI:width(text_2), y_zero-5, font_UI, COLOR.RED, COLOR.TRANSPARENT_BLACK)
end
if lens.hyperfocal >= dof_infinity then
text_1 = "X?X"
display.print(text_1, x_zero, y_zero-5, font_UI, COLOR.RED, COLOR.TRANSPARENT_BLACK)
else
if current_n_dof < 1000 then
text_1 = myround(current_n_dof/10, 0).."cm"
elseif current_n_dof < 10000 then
text_1 = myround(current_n_dof/1000,2).."m"
else
text_1 = myround(current_n_dof/1000,0).."m"
end
text_1 = "(f"..tostring(math.floor(1000*current_CoC+0.5)).."):"..text_1
if current_CoC >= diff_blur/1000 then
display.print(text_1, x_zero, y_zero-5, font_UI, COLOR.WHITE, COLOR.TRANSPARENT_BLACK)
else
display.print(text_1, x_zero, y_zero-5, font_UI, COLOR.YELLOW, COLOR.TRANSPARENT_BLACK)
end
end
-- now show blurs in use
if image_taken_past_H and not something_changed and DoF_Bar_Menu.submenu["Pro Mode"].value == "Blurs" and DoF_Bar_Menu.submenu["Bracketing"].value == CON and current_fl <= 50 then
text_2 = "(if"..tostring(math.floor(1000*infinity_blur + 0.5))..""..")"
local temp = display.width/2 - font_UI:width(text_2)/2
if h_based_fdof < h_based_ndof then
display.print(text_2, temp, y_zero-5, font_UI, COLOR.BLUE, COLOR.TRANSPARENT_BLACK)
else
display.print(text_2, temp, y_zero-5, font_UI, COLOR.MAGENTA, COLOR.TRANSPARENT_BLACK)
end
end
if DoF_Bar_Menu.submenu["Pro Mode"].value == "Brackets to H" and DoF_Bar_Menu.submenu["Bracketing"].value == CON and current_fp < H then
text_1 = "["..tostring(1+math.floor(0.5+H/(2*current_fp))).."->H]"
local temp = display.width/2 - font_UI:width(text_1)/2
display.print(text_1, temp, y_zero-5, font_UI, COLOR.WHITE, COLOR.TRANSPARENT_BLACK)
end
if DoF_Bar_Menu.submenu["Pro Mode"].value == "Show Focus" then
if current_fp < 1000 then
text_9 = myround(current_fp/10, 0).."cm"
elseif current_fp < 10000 then
text_9 = myround(current_fp/1000,2).."m"
else
text_9 = myround(current_fp/1000,0).."m"
end
if current_fp > infinity then text_9 = "Inf" end
display.print(text_9, display.width/2 - font_UI:width(text_9)/2, y_zero-5, font_UI, COLOR.WHITE, COLOR.TRANSPARENT_BLACK)
end
if lens.hyperfocal < dof_infinity then
-- now show current lower fiducials
display.circle(bar_x_pos(current_n_dof), lower_dots_pos , dot_size, COLOR.WHITE, COLOR.WHITE)
display.circle(bar_x_pos(current_f_dof), lower_dots_pos, dot_size, COLOR.WHITE, COLOR.WHITE)
display.circle(bar_x_pos(current_fp), lower_dots_pos, dot_size, COLOR.RED, COLOR.RED)
if current_f_dof > infinity then display.circle(bar_x_pos(current_f_dof), lower_dots_pos, dot_size, COLOR.WHITE, COLOR.BLACK) end
if current_f_dof < last_n_dof and image_taken and (not something_changed) and DoF_Bar_Menu.submenu["Bracketing"].value == CON then
display.circle(bar_x_pos(current_f_dof), lower_dots_pos, dot_size, COLOR.WHITE, COLOR.BLUE)
end
if current_n_dof > last_f_dof and image_taken and (not something_changed) and DoF_Bar_Menu.submenu["Bracketing"].value == CON then
display.circle(bar_x_pos(current_n_dof), lower_dots_pos, dot_size, COLOR.WHITE, COLOR.BLUE)
end
if image_taken_past_H and (not something_changed) and DoF_Bar_Menu.submenu["Bracketing"].value == CON then
if DoF_Bar_Menu.submenu["Pro Mode"].value == "Blurs" and current_fl <= 50 then
if h_based_fdof < h_based_ndof then
display.circle(bar_x_pos(h_based_fdof), lower_dots_pos, dot_size, COLOR.WHITE, COLOR.BLUE)
else
display.circle(bar_x_pos(h_based_fdof), lower_dots_pos, dot_size, COLOR.MAGENTA, COLOR.MAGENTA)
end
end
end
if current_fp > infinity then -- over focused
display.circle(bar_x_pos(current_n_dof), lower_dots_pos , dot_size, COLOR.DARK_GRAY, COLOR.DARK_GRAY)
display.circle(bar_x_pos(current_f_dof), lower_dots_pos, dot_size, COLOR.DARK_GRAY, COLOR.DARK_GRAY)
display.circle(bar_x_pos(current_fp), lower_dots_pos, dot_size, COLOR.DARK_GRAY, COLOR.DARK_GRAY)
end
-- now manage top fiducials showing the last image taken
if image_taken then -- at least one image has been taken
if not something_changed then
if DoF_Bar_Menu.submenu["Bracketing"].value == CON then
if DoF_Bar_Menu.submenu["Pro Mode"].value == "Blurs" and image_taken_past_H and current_fl <= 50 then
display.circle(bar_x_pos(h_based_ndof), bar_pos , dot_size, COLOR.MAGENTA, COLOR.MAGENTA)
end
display.circle(bar_x_pos(last_f_dof), bar_pos , dot_size, COLOR.WHITE, COLOR.WHITE)
display.circle(bar_x_pos(last_n_dof), bar_pos, dot_size, COLOR.WHITE, COLOR.WHITE)
display.circle(bar_x_pos(last_fp), bar_pos, dot_size, COLOR.RED, COLOR.RED)
if last_f_dof > infinity then display.circle(bar_x_pos(last_f_dof), bar_pos , dot_size, COLOR.WHITE, COLOR.BLACK) end
else
display.circle(bar_x_pos(current_n_dof), bar_pos , dot_size, COLOR.WHITE, COLOR.WHITE)
display.circle(bar_x_pos(current_f_dof), bar_pos, dot_size, COLOR.WHITE, COLOR.WHITE)
display.circle(bar_x_pos(current_fp), bar_pos, dot_size, COLOR.RED, COLOR.RED)
if current_f_dof > infinity then display.circle(bar_x_pos(current_f_dof), bar_pos, dot_size, COLOR.WHITE, COLOR.BLACK) end
end
end
end
end
--finally (re)draw the bars
display.rect(x_zero, bar_pos, bar_width, bar_depth,COLOR.GREEN2, COLOR.GREEN2)
display.rect(x_zero, bar_pos, (a_per*bar_width), bar_depth,COLOR.ALMOST_WHITE, COLOR.ALMOST_WHITE)
display.rect(bar_x_pos(H), bar_pos, c_per*bar_width, bar_depth,COLOR.LIGHT_GRAY, COLOR.LIGHT_GRAY)
display.rect(bar_x_pos(H) + c_per*bar_width/3, bar_pos, c_per*bar_width/3, bar_depth,COLOR.BLACK, COLOR.BLACK)
end
end
end
function draw_bar(arg)
if lens.dof_near ~= 0 and lens.dof_far ~= 0 and lens.focus_distance ~= 0 then -- OK to draw
if DoF_Bar_Menu.submenu["Show Bar"].value == CON then -- show DoF Bar
if camera.aperture.value ~= last_ap or lens.focal_length ~= last_fl or lens.hyperfocal ~= last_H then -- things have changed so reset
something_changed = true
image_taken = false
last_current_fp = 0
image_taken_past_H = false
current_CoC = lens.focal_length*lens.focal_length/(camera.aperture.value*(lens.hyperfocal-2*lens.focal_length))
end
H = lens.hyperfocal
b_c_logic = H
if H <= DoF_Bar_Menu.submenu["Min focus"].value then DoF_Bar_Menu.submenu["Min focus"].value = 4*current_fl end
current_f_dof = lens.dof_far
current_fp = lens.focus_distance
if current_fp > infinity then current_n_dof = H else current_n_dof = lens.dof_near end
last_ap = camera.aperture.value
current_fl = lens.focal_length
last_fl = lens.focal_length
last_H = H
if dryos.shooting_card.file_number ~= card_count then -- an image has been taken so show/update things
last_n_dof = current_n_dof
last_f_dof = current_f_dof
last_fp = current_fp
image_taken = true
card_count = dryos.shooting_card.file_number -- reset card counter
something_changed = false
if current_fp > H and current_fp <= 4*H and image_taken_past_H == false then -- hence define h as the current focus.
-- and remember a couple of things until reset detected by change in aperture, focal length or H
h = current_fp
image_taken_past_H = true
infinity_blur = current_infinity_blur
end
end
if image_taken_past_H then
if current_fp > infinity then
h_based_ndof = H
else
h_based_ndof = (h*last_fp - last_fl*last_fl)/(h-2*last_fl+last_fp) + last_fl
end
if h > current_fp then
h_based_fdof = (h*current_fp - 2*lens.focal_length*current_fp + lens.focal_length*lens.focal_length)/(h - current_fp) + lens.focal_length
if h_based_fdof > current_f_dof then h_based_fdof = current_f_dof end -- hack: as we are mixing H and h will will get some inconsistancies at short focus distances
else
h_based_fdof = infinity
end
end
if (last_current_fp ~= current_fp or screen_refresh) and lv.overlays == 2 and not menu.visible then -- need to update bar
display.draw(show_focus_bar)
screen_refresh = false
end
if not menu.visible and lv.overlays == 2 then last_current_fp = current_fp else last_current_fp = 0 end
end
end
end
DoF_Bar_Menu = menu.new
{
parent = "Focus",
name = "DoF Bar",
help = "Shows current DoFs, infinity blur and supports bracketing",
depends_on = DEPENDS_ON.LIVEVIEW,
submenu =
{
{
name = "Show Bar",
help = "Switches the DoF bar on & off",
choices = {CON,COFF},
},
{
name = "Min focus",
help = "In mm:Max = 1000; Default is 500mm.",
help2 = "Minimum = 4 * focal length",
min = 4*lens.focal_length,
max = min + 800,
value = 500
},
{
name = "Bracketing",
help = "On provides info on last capture on the bar's top",
choices = {COFF,CON},
},
{
name = "Pro Mode",
help = "Shows additional info related to focus or bracketing",
help2 = "Blurs option shows ML set and Infinity Blur if set",
choices = pro_choices,
},
{
name = "Dynamic Bar",
help = "Adjust DoF Bar when focus less than the hyperfocal: a zoom feature",
help2 = "Note DoF Bar may change if your min is too large, ie > H",
choices = dynamic_choices
},
}
}
event.shoot_task = draw_bar
config.create_from_menu(DoF_Bar_Menu) -- keep a track of the script's menu state at camera close
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment