DoF Bar
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- 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