Last active
December 23, 2017 21:25
-
-
Save pigeonhill/cd1dbe0191ca1264fc0aa07aaafb515d to your computer and use it in GitHub Desktop.
Focus 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
--[[ | |
Focus Bar Script (Version 3.37) | |
******* ENSURE YOU CHANGE LINES 155/156 TO YOUR CAMERA ******* | |
Menu config is saved, so once you have found your prefered set up, the script will always start in that state. Script works well with the Toggler script. | |
This script provides a focus bar for visualising the focus defocus field, as well as providing feedback for focus bracketing. ' | |
The script may be switched on and off by doing a halfshutter press longer than 3 sces (the led will blink). The default at camera start up is: off. | |
A half shutter press of 6+ seconds will toggle the simple DoF mode into full, ie showing more info. | |
Warning: a long AF attempt may also switch on/off the script :-( | |
This version will work on all ML enabled cameras with the (experimental) Lua Fix Build (2017-12-03 22:09) | |
This script switches off ML DoF display, as the script generates all DoFs, and displays them. | |
The lens must report distance and aperature, and LV needs to be on: but you don't need to have an AF lens. The script checks this. | |
Check the ML CoC (total blur) is set for your needs. The script uses this value. | |
The script has been tested on a 5D3 and EOSM. | |
If focusing past the hyperfocal, the near field DoF distance shown meets the total (diffraction (if requested in the script) + defocus) blur at infinity. | |
If the far DoF defocus blur feedback at infinity turns from green to red (vertical inner bar), you are beyond the 2xsensor pixel limit. | |
If the whole (horizontal) focus bar bar turns red, then you are focusing beyond lens-reported infinity and need to back off. The script will warn you of this. | |
Note that there is a linear relationship between total blur and the achievable print quality. A typical blur of, say, 30 microns on a Full Frame | |
(reduce by the crop on a cropped sensor) is OK for screen presentation. If printing this equates to about 5 lp/mm at arms distance away. | |
For high quality printing you should be seeking to multiple the lp/mm by 1.5 or 2, ie halfing the total (sic) blur (blue bar) to, say, 15 microns. | |
When infinity focusing the white vertical bar represents the ML set, total blur value, which is displayed at the bottom, ie ndof(ML-blur)fdof | |
For 'normal' viewing, aim for total (ie blue bar) far DoF (micron) blurs at infinity of lower than 30 (/crop), but not lower than, say, 12 (/crop). | |
Also note that diffraction blur is assumed 'flat' over the entire DoF and, to some extent, you might be able to reduce it in post, albeit with the risk of some artifacts. | |
The defocus blur varies over the scene and is only zero at the plane of focus. This can't be reduced in post, ie you need to get it right in camera. | |
The focus bar's response is changed via the following parameters: | |
- Unity Blur Multiplier: controls the max of the focus bar gray zone, ie multiplier of 5 = 5 x the ML set blur value | |
- Unity Blur: Optical or with diffraction | |
- Focus Bar Multiplier: this allows you to stretch out the zone of interest of the end of the focus bar, ie a multiplier of 1 = zero to far-DoF. A multiplier of > 1 | |
means zoom out. The distance of the zoom bar into the field is shown in meters. The start of the focus bar is as defined, eg zero of near depth of field. | |
Note a setting of 0 represents a special and useful mode. In the zero mode the end of the focus bar is set to the focus point and the start to zero, ie the sensor plane. | |
A setting of -1 switches the bar to DoF mode, near-dof to far-dof. This is the default mode. | |
A setting of -2 forces the use of the start and finish distances in the function call: but this is not accessible via the script's menu. | |
A useful thing to note is that the Focus Bar works in Canon zoom mode :-) Thus DoF mode (-1) and zoomed in may be useful for some capture workflows. | |
If the far DoF goes beyond the HFD, ie you move into infinity focusing mode, and the far DoF scale will switch from showing a distance, | |
to show the defocus blur and the near scale (if info option is Full) will switch to show the near DoF distance based on the infinity blur option selected in the menu, | |
ie infinity defocus, 2 x infinity defocus, or defocus based on the CoC ML criterion, ie accounting for diffraction. | |
Thus you have all the data you need for tack sharp capture, eg: | |
- Toal blur info (in microns) at infinity, ie when focused beyond the HFD | |
- Focus bar showing an impression of the (optical) focus field from the camera to the focus point | |
- In DoF mode an impression of the blur diameters as they vary between the DoFs | |
Blurs in the focus bar greater or less than unity (referenced to the ML setting of blur or CoC) are shown in gray, blurs at unity are black. | |
Blurs in the focus bar above or below unity are also shown in grey. | |
Blurs in the focus bar below the sensor blur limit (2 x pixel size) are cyan. | |
Blurs in the focus bar above the blur max you set are red. | |
The generic layout of the focus bar looks like this: | |
[X][--R--][W--G--B][NDoF][B--W][sen][FP][sen][W--B][FDoF][B--G--W][--R--][Y] | |
W=White, B=Black, G=Grey, R=Red, FP=Focus Plane, sen = sensor limited blur, X=focus bar start distance, Y=focus bar end distance or info | |
Although at first the 'continuuum of grey' and colour may look confusing, all is clear once you use the near and far DoFs (green dot) and the focus point (dark grey dot) as your references. | |
The blur data at infinity can be switched off so you just have the focus bar showing. | |
NOTE: Change the script's menu settings to create your 'defaults at start up'. | |
NOTE: All displayed distances are referenced to the sensor plane. | |
In focus stacking mode the DoFs at the bottom show the DoF of the last image taken. These will be 0 at camera start up, ie until an image is taken. | |
The number inbetween the near and far DoFs, at the bottom of the screen, is the defocus blur, ie the ML set CoC/blur criterion less the effect of diffraction (as set in the ML menu (sic)) | |
To switch off (or on) the focus stacking, simply move the lens to the infinity position and do a 3-5 sec half shutter press (the led will blink 3 times). Stacking is defaulted off at startup. | |
To repeat: for the landscape photographers (or anyone) I recommend setting the script's diffraction aware on and DoF visible, thus the green dots are providing you | |
info on the DoF with diffraction. | |
Bottom line: try and minimise the total blur in camera if you can: post processing will corrupt your captured data ;-) | |
Garry George December 2017 | |
http://photography.grayheron.net/ | |
--]] | |
-- Set up and test some stuff | |
if (lens.focus_distance == 0 or camera.aperture.value == 0 or camera.focal_length == 0) then | |
display.notify_box("Sorry can't run Focus Bar Script: check lens", 4000) | |
return | |
end | |
b_inf = 0 | |
b_total = 0 | |
b_near = 0 | |
b_near2 = 0 | |
require("config") | |
fb_on_test = true | |
timer = 0 | |
time = -1 | |
screen_dirty = false | |
full_press = false | |
timer_running = false | |
menu.set("DOF Settings","DOF info in LiveView",0) -- switch off ML contolled DoF info | |
CON = "ON" | |
COFF = "OFF" | |
options = {"Defocus","2xDefocus"} | |
options2 = {"Full","Simple"} | |
last_ndof = 0 | |
last_fdof = 0 | |
last_fp = 0 | |
current_ndof = 0 -- at the time a full press is made | |
current_fdof = 0 | |
current_fp = 0 | |
inf = 999999 -- Trap for ML reported infinity in mm - used for DoFs | |
fp_inf = 655000 -- Trap for Canon lens reported infinity in mm - used for FP | |
last_fd_LT_H = false | |
blinked1 = true | |
blinked2 = true | |
blinked3 = true | |
blinked4 = true | |
delay_key_press = false | |
overlaping = false | |
check_FB = false | |
last_focus_distance = 0 | |
last_aperture = 0 | |
last_focal_length = 0 | |
update_set = false | |
delay_key = 0 | |
message1 = "" | |
message2 = "" | |
message3 = "" | |
--** The following two functions, if used in another script, must be used together, with the added global hidden = false variable ** | |
function myround(num,dp) | |
-- Used by function focus_bar() | |
if dp == 0 then | |
local int = math.floor(num+0.5) | |
return tostring(int) | |
else | |
local int = math.floor(num) | |
local frac = math.floor((num-int)*(10^dp)) | |
return tostring(int).."."..tostring(frac) | |
end | |
end | |
function focus_bar(showing,start,finish,info,b_max,zoom,diff) | |
--[[ | |
Focus Bar Function: used to show a linear-distance-scale (sic) representation of the focus field | |
*********************************************************************************** | |
* Note: Focus Bar Function requires global variable to be defined: hidden = false * | |
* Note: Focus Bar Function also uses function myround * | |
*********************************************************************************** | |
showing = focus bar visible : true or false | |
start = left hand real world end of focus bar, eg 0 or lens dof_near or any scene depth you are interested in | |
finish = right hand real world end of focus bar, eg lens dof_far or lens fd or any scene depth you are interested in | |
info = additional near DOF info visible : true or false | |
b_max = max blur, relative to unity blur (optical or with diffraction), ie start of red zone. 0 = FP mode | |
zoom = zoom far focus bar out. Zoom is used like this : end of focus bar = (zoom-1)*(dof_far-fd) + dof_far | |
diff = diffraction on or off : true or false | |
The lens must report distance and LV needs to be on. | |
Has been tested on a 5D3 and EOSM. | |
http://photography.grayheron.net/ | |
--]] | |
-- Change the next two lines to suit your camera | |
if showing and not console.visible then | |
do | |
local sensor = 4.29 -- change this to match your camera pixel pitch or pixel size. EOSM = 4.29. 5D3 = 6.3 | |
local freq = 0.550 -- use 0.550 for visible (normal) and 0.850 for IR (or your choice) | |
local message = "" | |
local num_brackets = 0 | |
local b_limit = sensor*2 -- smallest total blur that is sensible to aim for | |
local fl = lens.focal_length -- lock the next few varables together in time | |
last_focus_distance = lens.focus_distance | |
local fd = lens.focus_distance - fl -- referenced to approx lens (principal) plane | |
local N = camera.aperture.value | |
last_aperture = N | |
last_focal_length = fl | |
local unity_blur = menu.get("DOF Settings","Circle of Confusion",0) -- ML set total blur criterion | |
local fb_blur = unity_blur | |
local fb_blur_fp = unity_blur | |
local b_diff = 2.44*freq*N -- visible diffraction blur at infinity in microns, ie magnification = 0 | |
local b_diff_fp = b_diff*fd/(fd-fl) -- diffraction at fp, ie with magnification (really only kicks in for close work) - not used in this version of the script | |
-- This script switchs off the DoF displayed by ML and calculates all DoF info | |
if diff then -- calculate defocus blur without diffraction, ie to meet the ML-set total blur or CoC | |
fb_blur = math.sqrt(unity_blur*unity_blur - b_diff*b_diff) | |
fb_blur_fp = math.sqrt(unity_blur*unity_blur - b_diff_fp*b_diff_fp) -- but not used at the moment | |
else | |
fb_blur = unity_blur | |
fb_blur_fp = unity_blur | |
b_diff = 0 | |
b_diff_fp = 0 | |
end | |
local H = fl + 1000*fl*fl/(N*fb_blur) -- HFD relative to principal lens plane, ie about (sic) a focal length less than to the sensor plane | |
local focus_bar_ndof = (fd*H-fl*fl)/(H+fd-2*fl) -- referenced to lens | |
local focus_bar_fdof = (fd*H-2*fl*fd+fl*fl)/(H-fd) -- referenced to lens | |
if fd >= H then | |
focus_bar_fdof = inf | |
else | |
num_brackets = math.ceil((1 + H/fd)/2) | |
end | |
current_fdof = focus_bar_fdof -- used for focus stacking feedback | |
current_ndof = focus_bar_ndof -- used for focus stacking feedback | |
current_fp = fd | |
if focus_bar_fdof >= inf or focus_bar_fdof < 0 then focus_bar_fdof = inf end | |
local pos_x = 10 | |
local pos_y = 40 | |
local num_steps = 233 -- tunable but note you only have 700 LV pixels to play with. 100 is good. 233 is a max ;-) | |
local h = 11 -- focus bar height | |
local w = 3 -- 700.0/(num_steps) -- focus bar width = 700 | |
local x_end = finish | |
local x_start = start | |
local x_step = 0 | |
local temp = 0 | |
if zoom == 0 then -- configure focus bar to show FP on the right | |
x_start = 0 | |
x_end = fd | |
elseif zoom == -1 then -- configure for DoF mode | |
x_start = focus_bar_ndof | |
x_end = focus_bar_fdof | |
elseif zoom == -2 then | |
x_start = start | |
x_end = finish | |
else -- configure for 0 to focus_bar_fdof*multiplier mode | |
x_start = 0 | |
if focus_bar_fdof < inf then | |
x_end = (zoom-1)*(focus_bar_fdof-fd) + focus_bar_fdof | |
if x_end > inf then x_end = inf end | |
else | |
x_end = focus_bar_fdof + fl | |
end | |
end | |
if ((not last_fd_LT_H) and fd < H) then -- look after info display state change | |
clear_fb(true) | |
last_fd_LT_H = true | |
end | |
local D = fl/N | |
b_inf = 1000*(fl*fl)/(N*(fd-fl)) -- defocus blur at infinity in microns | |
b_total = math.sqrt(b_inf*b_inf + b_diff*b_diff) -- Total blur in quadrature at infinity in microns | |
b_near = b_inf*(fd-fl)/1000.0 -- near DoF using defocus blur at infinity, referenced to sensor | |
b_near = D*fl*fd/(b_near + D*fl) | |
b_near2 = 2*b_inf*(fd-fl)/1000 -- near DoF using twice the defocus blur at infinity, referenced to sensor | |
b_near2 = D*fl*fd/(b_near2 + D*fl) | |
x_step = (x_end - x_start)/num_steps | |
local x = 0 -- point of interest in the scene, relative to lens | |
local b_x = 0 -- blur at x | |
local percent = 0 -- % blur relative to blur max and unity blur | |
local old_pos = 5 -- used to manage points | |
local old_pos2 = 5 | |
local old_pos3 = 5 | |
local wx = 0 | |
b_max = b_max * unity_blur -- entering the red zone | |
display.circle(5, pos_y+6, 5, COLOR.TRANSPARENT,COLOR.TRANSPARENT) -- clean up just in case | |
display.circle(715, pos_y+6, 5, COLOR.TRANSPARENT,COLOR.TRANSPARENT) | |
local fld = (1000*fl*fl/N) | |
local fdfl = (fd - fl) | |
local bxub = (b_max-unity_blur) | |
overlaping = false | |
for i = 1, num_steps, 1 | |
do | |
wx = 10 + math.floor(w*(i-1)) | |
x = x_start + x_step*i - x_step/2 | |
b_x = (fd - x) / (fdfl*(x)) | |
b_x = fld*math.abs(b_x) | |
if b_x >= b_max or (focus_bar_ndof == focus_bar_fdof) or fd >= fp_inf then | |
display.rect(wx, pos_y, w, h, COLOR.RED, COLOR.RED) | |
elseif b_x < b_max and b_x > unity_blur then | |
percent = math.floor(100*(b_x - unity_blur)/bxub) | |
if percent < 0 then percent = 0 end -- just in case | |
if percent > 100 then percent = 100 end -- just in case | |
display.rect(wx, pos_y, w, h, COLOR.gray(percent), COLOR.gray(percent)) | |
elseif b_x <= unity_blur then | |
percent = math.floor(100*(unity_blur - b_x)/(unity_blur)) | |
if percent < 0 then percent = 0 end -- just in case | |
if percent > 100 then percent = 100 end -- just in case | |
if b_x > b_limit then display.rect(wx, pos_y, w, h, COLOR.gray(percent), COLOR.gray(percent)) end | |
if b_x <= b_limit then display.rect(wx, pos_y, w, h, COLOR.CYAN, COLOR.CYAN) end | |
end | |
if zoom == -1 and Focus_Bar_Menu.submenu["Focus Stacking"].value == "ON" then | |
if (focus_bar_ndof < last_ndof ) and (x > last_ndof) then | |
display.rect(wx, pos_y, w, h, COLOR.MAGENTA, COLOR.MAGENTA) | |
overlaping = true | |
elseif (focus_bar_fdof > last_fdof) and (x < last_fdof) then | |
display.rect(wx, pos_y, w, h, COLOR.MAGENTA, COLOR.MAGENTA) | |
overlaping = true | |
end | |
end | |
end | |
-- display ML far DoF point | |
display.circle(old_pos3, pos_y+6, 4, COLOR.TRANSPARENT,COLOR.TRANSPARENT) -- clean up previous points | |
display.circle(715, pos_y+6, 4, COLOR.TRANSPARENT,COLOR.TRANSPARENT) | |
display.circle(5, pos_y+6, 4, COLOR.TRANSPARENT,COLOR.TRANSPARENT) | |
if focus_bar_fdof < x_end then | |
pos_x = 10 + math.floor(700*(focus_bar_fdof-x_start)/(x_end - x_start)) | |
else | |
pos_x = 715 | |
end | |
if pos_x >= 710 then pos_x = 715 end | |
if pos_x <= 10 then pos_x = 5 end | |
if focus_bar_fdof > inf then pos_x = 715 end | |
old_pos3 = pos_x | |
display.circle(pos_x, pos_y+6, 4, COLOR.GREEN1,COLOR.GREEN1) | |
-- display focus point | |
display.circle(old_pos, pos_y+6, 4, COLOR.TRANSPARENT,COLOR.TRANSPARENT) | |
if fd > x_start then | |
pos_x = 10 + math.floor(700*(fd-x_start)/(x_end - x_start)) | |
else | |
pos_x = 5 | |
end | |
if pos_x > 710 then pos_x = 715 end | |
if pos_x <= 10 then pos_x = 5 end | |
if fd > fp_inf then pos_x = 715 end | |
old_pos = pos_x | |
display.circle(pos_x, pos_y+6, 4, COLOR.DARK_GRAY,COLOR.DARK_GRAY) | |
-- display ML near DoF point | |
display.circle(old_pos2, pos_y+6, 4, COLOR.TRANSPARENT,COLOR.TRANSPARENT) | |
if focus_bar_ndof > x_start then | |
pos_x = 10 + math.floor(700*(focus_bar_ndof-x_start)/(x_end- x_start)) | |
else | |
pos_x = 5 | |
end | |
if pos_x > 710 then pos_x = 715 end | |
if pos_x <= 10 then pos_x = 5 end | |
old_pos2 = pos_x | |
display.circle(pos_x, pos_y+6, 4, COLOR.GREEN1,COLOR.GREEN1) | |
-- display % marks if in DoF mode | |
if zoom == -1 then | |
x = 0 | |
local r = 0 | |
for i = 1, 9, 1 | |
do | |
pos_x = 10 + math.floor(700*i/10) | |
x = x_start + i*(x_end-x_start)/10 | |
b_x = (fd - x) / ((fd - fl)*x) | |
b_x = (1000*fl*fl/N)*math.abs(b_x) | |
r = (h+1)*(b_x/unity_blur)/2 | |
if r == 0 then r=1 end | |
if b_x > b_limit then | |
display.circle(pos_x, pos_y+h/2, r, COLOR.BLACK,COLOR.BLACK) | |
else | |
display.circle(pos_x, pos_y+h/2, r, COLOR.RED,COLOR.RED) | |
end | |
end | |
end | |
-- display focus bar distance info: first the far field info | |
local qq = 0 | |
qq = FONT.LARGE:width(message2) | |
display.print(message2, 720-qq, 53, FONT.LARGE ,COLOR.TRANSPARENT,COLOR.TRANSPARENT) | |
temp = x_end + fl | |
if focus_bar_fdof >= inf then | |
temp = b_total | |
if focus_bar_fdof == focus_bar_ndof then temp = 0 end | |
if b_inf > b_limit then | |
message2 = " Inf:"..myround(temp,0).." " | |
qq = FONT.LARGE:width(message2) | |
display.print(message2, 720-qq, 53, FONT.LARGE ,COLOR.GREEN1,COLOR.WHITE) | |
else | |
message2 = " Inf:"..myround(temp,0).." " | |
qq = FONT.LARGE:width(message2) | |
display.print(message2, 720-qq, 53, FONT.LARGE ,COLOR.RED,COLOR.WHITE) | |
end | |
if Focus_Bar_Menu.submenu["Near DoF Criterion"].value == "Defocus" then | |
x_start = b_near | |
elseif Focus_Bar_Menu.submenu["Near DoF Criterion"].value == "2xDefocus" then | |
x_start = b_near2 | |
end | |
-- Focus breakdown at Infinity (Yellow = diffraction, Green or Red = defocus, Blue = total blur, White = total CoC or blur set in ML menu) | |
-- First the infinity blur breakdown (graphically) | |
if fd >= H then | |
display.rect(690, 100, 30, 135, COLOR.BLACK, COLOR.WHITE) | |
local h1 = 135*b_total/unity_blur | |
display.rect(690, 235-h1, 30, h1, COLOR.BLACK, COLOR.BLUE) | |
h1 = 135*b_diff/unity_blur | |
display.rect(690, 235-h1, 30, h1, COLOR.BLACK, COLOR.YELLOW) | |
local hh = 135*b_inf/unity_blur | |
if b_inf >= b_limit then | |
display.rect(700, 235-hh, 10, hh, COLOR.BLACK, COLOR.GREEN1) | |
else | |
display.rect(700, 235-hh, 10, hh, COLOR.BLACK, COLOR.RED) | |
end | |
last_fd_LT_H = false | |
end | |
-- Now the near field distance info | |
if info == "Full" then | |
display.rect(0, 100, 280, 135, COLOR.WHITE, COLOR.WHITE) | |
local temp_info = b_near + fl | |
if temp_info < 1000 then | |
message = "Defocus: "..myround(temp_info/10, 0).."cm " | |
else | |
message = "Defocus: "..myround(temp_info/1000,2).."m " | |
end | |
if fd > fp_inf then message = " ***WARNING***" end | |
display.print(message, 5, 110, FONT.LARGE,COLOR.BLACK,COLOR.WHITE) | |
temp_info = b_near2 + fl | |
if temp_info < 1000 then | |
message = "Defocus2: "..myround(temp_info/10, 0).."cm " | |
else | |
message = "Defocus2: "..myround(temp_info/1000,2).."m " | |
end | |
if fd > fp_inf then message = " Over focused at" end | |
display.print(message, 5, 140, FONT.LARGE,COLOR.BLACK,COLOR.WHITE) | |
temp_info = focus_bar_ndof + fl | |
if temp_info < 1000 then | |
message = "CoC-Def: "..myround(temp_info/10, 0).."cm " | |
else | |
message = "CoC-Def: "..myround(temp_info/1000,2).."m " | |
end | |
if fd > fp_inf then message = " infinity: Back off" end | |
display.print(message, 5, 170, FONT.LARGE,COLOR.BLACK,COLOR.WHITE) | |
last_fd_LT_H = false | |
-- show focus quality factor (FQF) of infinity defocus blur. 100 = Hyperfocal defocus blur, ie the 'just acceptable' figure based on the set ML CoC criterion | |
if b_inf < b_limit then | |
message = "FQF=MAX="..myround(100*fb_blur/b_limit, 0) | |
display.print(message, 5, 200, FONT.LARGE,COLOR.RED,COLOR.WHITE) | |
else | |
message = "FQF="..myround(100*fb_blur/b_inf, 0) | |
display.print(message, 5, 200, FONT.LARGE,COLOR.BLACK,COLOR.WHITE) | |
end | |
end | |
else | |
if focus_bar_fdof == focus_bar_ndof then temp = 0 end | |
if temp < 1000 then | |
message2 = " "..myround(temp/10, 0).."cm " | |
else | |
message2 = " "..myround(temp/1000,2).."m " | |
end | |
if focus_bar_fdof >= inf then message = "-> infinity" end | |
qq = FONT.LARGE:width(message2) | |
display.print(message2, 720-qq, 53, FONT.LARGE ,COLOR.WHITE,COLOR.TRANSPARENT_BLACK) | |
last_fd_LT_H = true | |
end | |
-- Now the near field FB display | |
temp = x_start + fl | |
if temp < 2*fl then temp = 0 end | |
display.print(message1, 20, 53, FONT.LARGE ,COLOR.TRANSPARENT,COLOR.TRANSPARENT) | |
if temp < 1000 then | |
message1 = myround(temp/10, 0).."cm " | |
else | |
message1 = myround(temp/1000,2).."m " | |
end | |
-- show overlap blur if focus stacking | |
if overlaping and zoom == -1 and Focus_Bar_Menu.submenu["Focus Stacking"].value == "ON" then | |
local b1 = fl*last_fp/(last_fp-fl) | |
local b2 = fl*current_fp/(current_fp-fl) | |
local overlap_z = math.abs(b2+b1)/2.0 | |
local overlap_blur = 1000*(fl/N)*math.abs(overlap_z-b1)/(overlap_z) | |
message1 = message1.." ("..myround(overlap_blur,0)..")" | |
end | |
if num_brackets ~= 0 then | |
message1 = message1.." ["..tostring(num_brackets).."]" | |
end | |
if focus_bar_fdof >= inf then | |
if fd > fp_inf then message1 = "?" end | |
message1 = " DoF:"..message1 | |
if b_inf > b_limit then | |
display.print(message1, 0, 53, FONT.LARGE ,COLOR.GREEN1,COLOR.WHITE) | |
else | |
display.print(message1, 0, 53, FONT.LARGE ,COLOR.RED,COLOR.WHITE) | |
end | |
else | |
message1 = " "..message1 | |
display.print(message1, 0, 53, FONT.LARGE ,COLOR.WHITE,COLOR.TRANSPARENT_BLACK) | |
end | |
-- Now the DoFs (which show the non-infinity DoFs, calculated from the CoC (diffraction corrected or not)) | |
local xpos = 380 | |
qq = FONT.LARGE:width(message3) | |
display.print(message3, xpos-qq/2, 410, FONT.LARGE ,COLOR.TRANSPARENT,COLOR.TRANSPARENT) | |
temp = focus_bar_ndof + fl | |
if zoom == -1 and Focus_Bar_Menu.submenu["Focus Stacking"].value == "ON" then temp = last_ndof + fl end | |
if temp < 2*fl then temp = 0 end | |
if temp < 1000 then | |
message3 = myround(temp/10, 0).."cm" | |
else | |
message3 = myround(temp/1000,2).."m" | |
end | |
if fb_blur >= 9.5 then | |
message3 = message3.." ("..myround(fb_blur,0)..") " | |
else | |
message3 = message3.." ( "..myround(fb_blur,0)..") " | |
end | |
temp = focus_bar_fdof + fl | |
if zoom == -1 and Focus_Bar_Menu.submenu["Focus Stacking"].value == "ON" then temp = last_fdof + fl end | |
if temp < 2*fl then temp = 0 end | |
if temp >= inf then | |
message3 = message3.."Inf" | |
elseif temp < 1000 then | |
message3 = message3..myround(temp/10, 0).."cm" | |
else | |
message3 = message3..myround(temp/1000,2).."m" | |
end | |
qq = FONT.LARGE:width(message3) | |
display.print(message3, xpos-qq/2, 410, FONT.LARGE ,COLOR.WHITE,COLOR.TRANSPARENT_BLACK) | |
end | |
end | |
end | |
function show_focus_bar() | |
--focus_bar(showing,start,finish,info,b_max,zoom,diff) maps to focus_bar(a,b,c,d,e,f,g) | |
local a = true | |
local b = 500 -- Note, although not used in this demo script, function will use explicit distances, b & c, if zoom option is -2 | |
local c = 3000 | |
local d = true | |
local g = true | |
if Focus_Bar_Menu.submenu["Display"].value == "ON" then | |
a = true | |
else | |
a = false | |
end | |
d = Focus_Bar_Menu.submenu["Show Info"].value | |
if Focus_Bar_Menu.submenu["Diffraction"].value == "ON" then | |
g = true | |
else | |
g = false | |
end | |
local f = Focus_Bar_Menu.submenu["Focus Bar Multiplier"].value | |
local e = Focus_Bar_Menu.submenu["Unity Blur Multiplier"].value | |
focus_bar(a,b,c,d,e,f,g) | |
end | |
function clear_screen() | |
display.clear() | |
screen_dirty = false | |
check_FB = false | |
timer = 0 | |
key.press(KEY.HALFSHUTTER) | |
key.press(KEY.UNPRESS_HALFSHUTTER) | |
end | |
function update() | |
if (last_focus_distance ~= lens.focus_distance or last_aperture ~= camera.aperture.value or last_focal_length ~= lens.focal_length) or not update_set then | |
update_set = true | |
return true | |
else | |
return false | |
end | |
end | |
function check_requests(arg) | |
if lv.running then | |
local time_now = dryos.clock | |
if time_now - time >= 6 and (not blinked4) and timer_running and current_fp > fp_inf then | |
led_blink(4,100,100) | |
blinked4 = true | |
elseif time_now - time >= 6 and (not blinked2) and timer_running then | |
led_blink(2,100,100) | |
blinked2 = true | |
elseif time_now - time >= 3 and (not blinked3) and timer_running and current_fp > fp_inf then | |
led_blink(3,100,100) | |
blinked3 = true | |
elseif time_now - time >= 3 and (not blinked1) and timer_running then | |
led_blink(1,100,100) | |
blinked1 = true | |
end | |
if timer >= 6 and (not timer_running) and current_fp > fp_inf and (not full_press) then | |
last_fdof = 0 | |
last_ndof = 0 | |
timer = 0 | |
if Focus_Bar_Menu.submenu["Focus Stacking"].value == "ON" then | |
menu.set("Focus Bar","Focus Stacking","OFF") | |
else | |
menu.set("Focus Bar","Focus Stacking","ON") | |
end | |
elseif timer >= 3 and (not timer_running) and current_fp > fp_inf and (not full_press) then | |
last_fdof = 0 | |
last_ndof = 0 | |
timer = 0 | |
elseif timer >= 6 and (not timer_running) and (not full_press) then | |
fb_on_test = not fb_on_test | |
if not fb_on_test then check_FB = false end | |
if Focus_Bar_Menu.submenu["Show Info"].value == "Full" then | |
menu.set("Focus Bar","Show Info","Simple") | |
elseif Focus_Bar_Menu.submenu["Show Info"].value == "Simple" then | |
menu.set("Focus Bar","Show Info","Full") | |
end | |
timer = 0 | |
elseif timer >= 3 and timer < 5 and (not timer_running) and (not full_press) then | |
fb_on_test = not fb_on_test | |
if not fb_on_test then check_FB = false end | |
timer = 0 | |
end | |
if delay_key_press then -- handle delayed key | |
if fb_on_test then | |
display.draw(clear_screen) | |
screen_dirty = false | |
end | |
delay_key_press = false | |
key.press(delay_key) | |
task.yield(100) | |
end | |
if lv.overlays == 2 and not console.visible then | |
if fb_on_test and Focus_Bar_Menu.submenu["Display"].value == "ON" then | |
if Focus_Bar_Menu.submenu["update"].value == "ON" then | |
check_FB = false | |
clear_fb(true) | |
menu.set("Focus Bar","update","OFF") | |
end | |
if not check_FB then | |
display.draw(show_focus_bar) | |
screen_dirty = true | |
check_FB = true | |
elseif update() then | |
display.draw(show_focus_bar) | |
screen_dirty = true | |
end | |
else | |
if screen_dirty then | |
display.draw(clear_screen) | |
end | |
end | |
end | |
end | |
return true | |
end | |
function clear_fb(arg) | |
if Focus_Bar_Menu.submenu["Show Info"].value == "Full" or arg then | |
display.rect(0,80, 720,160,COLOR.TRANSPARENT,COLOR.TRANSPARENT) | |
elseif Focus_Bar_Menu.submenu["Show Info"].value == "Simple" or arg then | |
display.rect(680, 100, 30, 100, COLOR.TRANSPARENT, COLOR.TRANSPARENT) | |
end | |
key.press(KEY.HALFSHUTTER) | |
key.press(KEY.UNPRESS_HALFSHUTTER) | |
end | |
function property.HALF_SHUTTER:handler(value) | |
check_FB = false | |
end | |
function property.GUI_STATE:handler(value) | |
check_FB = false | |
end | |
function property.BV:handler(value) | |
check_FB = false | |
end | |
function test4dof(k) | |
if k == KEY.FULLSHUTTER then -- set the last DoFs to the current DoFs (if requested) | |
if Focus_Bar_Menu.submenu["Focus Bar Multiplier"].value == -1 and Focus_Bar_Menu.submenu["Focus Stacking"].value == "ON" then | |
last_fdof = current_fdof | |
last_ndof = current_ndof | |
last_fp = current_fp | |
end | |
timer_running = false | |
timer = 0 | |
time = -1 | |
full_press = true | |
check_FB = false | |
return true | |
end | |
if k == KEY.HALFSHUTTER then | |
time = dryos.clock | |
timer_running = true | |
full_press = false | |
check_FB = false | |
return true | |
end | |
if k == KEY.UNPRESS_HALFSHUTTER and timer_running and (not full_press) then | |
timer = dryos.clock - time | |
timer_running = false | |
blinked1 = false | |
blinked2 = false | |
blinked3 = false | |
blinked4 = false | |
return true | |
end | |
if k == KEY.MENU or k == KEY.INFO then | |
delay_key = k | |
if fb_on_test and screen_dirty and not delay_key_press then -- focus bar showing | |
delay_key_press = true | |
return false -- delay action | |
else | |
delay_key_press = false | |
return true | |
end | |
end | |
return true | |
end | |
event.shoot_task = check_requests | |
event.keypress = test4dof | |
Focus_Bar_Menu = menu.new | |
{ | |
parent = "Focus", | |
name = "Focus Bar", | |
help = "Shows depth of field info", | |
depends_on = DEPENDS_ON.LIVEVIEW, | |
submenu = | |
{ | |
{ | |
name = "Display", | |
help = "Switches the focus bar display on & off", | |
choices = {CON,COFF}, | |
value = CON | |
}, | |
{ | |
name = "Show Info", | |
help = "Full shows additional near DoF info", | |
choices = options2, | |
value = "Simple" -- start up default | |
}, | |
{ | |
name = "Unity Blur Multiplier", | |
help = "Used for focus bar display, ie the red zone", | |
min = 1, | |
max = 10, | |
value = 5 -- start up default | |
}, | |
{ | |
name = "Diffraction", | |
help = "Switches the diffraction on & off in the focus bar", | |
help2 = "Focus Bar total blur is dynamically linked to ML total blur (CoC) setting", | |
choices = {CON,COFF}, | |
}, | |
{ | |
name = "Focus Bar Multiplier", | |
help = "Zoom out the focus bar by the specified amount", | |
help2 = "1 means no zoom. 0 = place FP at focus bar max. -1 = DoF mode", | |
min = -1, | |
max = 9, | |
value = -1 -- start up default | |
}, | |
{ | |
name = "Near DoF Criterion", | |
help = "Provides near DoF based on different infinity blurs", | |
help2 = "Based on the logic that near blur can be larger than the infinity blur", | |
choices = options, | |
value = "Defocus" -- start up default | |
}, | |
{ | |
name = "Focus Stacking", | |
help = "Only works in DoF mode", | |
help2 = "Magenta bar shows the amount of overlap re the last image", | |
choices = {CON,COFF}, | |
value = COFF -- start up default | |
}, | |
{ | |
name = "update", | |
help = "Not under user control", | |
choices = {CON,COFF}, | |
value = CON, -- start up default | |
hidden = true | |
} | |
} | |
} | |
config.create_from_menu(Focus_Bar_Menu) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment