Skip to content

Instantly share code, notes, and snippets.

# pigeonhill/DoF Bar.lua Last active Jan 18, 2019

DoF Bar
 -- DoF Bar -- Version 1.65 -- Released Dec 2018 -- 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 2018 ]] 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 = "" ok_to_use = true CON = "ON" COFF = "OFF" dynamic_choices = {"OFF", "Hyperfocal", "DoF"} pro_choices = {"OFF", "Blurs", "Brackets to H"} 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) 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 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.BLUE, 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.BLUE, 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.BLUE, 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 = 1000, value = 500 }, { name = "Bracketing", help = "On will provide additiona DoF info on the bar's top", choices = {COFF,CON}, }, { name = "Pro Mode", help = "Shows additional info related to bracketing, eg number to H", 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
to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.