M3 Focus & Exposure Bracketing
--[[ | |
@title M3 Bracketing | |
@chdk_version 1.5 | |
@subtitle Bracketing Settings | |
#mode = 0 "Focus bracket?" {Off X2INF Min2INF} | |
#bracket = 0 "Exposure bracket?" {Off +4Ev +3Ev +2Ev 2(+2Ev) 3(+2Ev) ISO1600 auto} | |
#sky = 0 "Sky Bracket?" {Off Sky+2Ev Sky+3Ev Sky+4Ev Sky+5Ev Sky+6Ev} | |
@subtitle Capture Settings | |
#infinity = 3 "Infinity focus (xH)" [2 4] | |
#overlap = 15 "Overlap (um)" [5 30] | |
#hilit = 20 "% histo HiLit" [5 30] | |
#pmag = 1 "Assumed Pupil Mag" [1 6] | |
@subtitle Other Settings | |
#dofs = 0 "DoF display" {Blur DoFs} | |
#traf = 0 "Traffic Lights" {Off On} | |
#sleep_time = 2 "Delay (s)" | |
#bookends = 1 "Bookends?" {Off On} | |
#screen_off = 0 "Screen?" {Off On} | |
#log = 0 "Log?" {Off On Reset} | |
#help = 0 "Console" {Off On} | |
#lens = 0 "Lens name?" {Off On} | |
Notes: | |
* Can only use registered EF-M lenses | |
* Script best used with WA lenses ;-) | |
* For retrofocus lenses use an assumed pupil mag at least as large as your guess. For telephoto use 1 | |
* Register your lens below in the lens_info() function | |
* Not designed for macro focus stacking, ie best for deep focus photography only | |
* To stop M3 flicker, cycle the Canon screen (INFO) to not show the Canon histogram etc | |
* If you reset/delete the log, you need set the log menu to on or off after | |
* When paused, at the assess point, you can refocus and see the impact on bracketing. You can also change focal length, but you need to press the RIGHT key to rest things | |
* If traffic light (TL) feedback is enabled, once an image is captured, the left hand TL shows the near DoF's focus overlap state, relative to the last image captured... | |
...and the right TL sows the far DoF's overlap state relative to the last image captured. Yellow = same focus; green = a positive overlap; red = a negative overlap (a gap). | |
In addition, as you manually focus bracket, the centre info area of the bar changes from showing the focal length and the number of bracket, to the fL and the blur at the overlap | |
* Use pmag to ensure focus overlap insurance. Use 1 for a telephoto lens and a value greater than what you think it is for a retrofocus lens | |
* Also at the assess point, you can exit ALT mode and change aperture. Reentering ALT and pressing the RIGHT key to reset things. | |
* Exposure bracketing and Sky Bracketing are mutually exclusive. To undertake sky bracketing you need to set exposure bracketing to zero. | |
* All console measurements, focus and near DoF, are relative to the sensor. | |
* Note: the script attempts to detect Canon mode changes, eg PLAY or MENU etc, but isn't perfect ;-) If the bar disappears, just press ALT on and off. | |
Release 2.2566 | |
photography.grayheron.net | |
April 2021 | |
--]] | |
require "drawings" | |
capmode = require("capmode") | |
bi = get_buildinfo() | |
set_console_autoredraw(1) | |
set_console_layout(0,0,45,1) | |
if (bi.platform ~= "m3") then error('Only runs on M3') end | |
if log == 2 then | |
print_screen(1) | |
print("Log reset") | |
print("Reset log menu") | |
print_screen(0) | |
return | |
end | |
function hH() -- calculate the full & short versions of the hyperfocal | |
n = av96_to_aperture(get_user_av96()) -- N*1000 | |
h = imath.mul(f,f) | |
temp = imath.mul(n,overlap) | |
h = imath.div(h,temp) | |
H = (f + h)/1000 -- 'full' hyperfocal in mm, as measured from the lens front principal, ie NOT the sensor as reported by Canon | |
end | |
function x2u(xx) | |
local temp = xx - t - (F*(1000+(Mmax*MFD)/xx))/1000 | |
return temp | |
end | |
press("shoot_half") | |
repeat sleep(10) until get_shooting() | |
dof = get_dofinfo() | |
f = dof.focal_length -- in microns | |
F = f / 1000 -- focal length in mm | |
s = get_tv96() | |
av = get_av96() | |
start_s = s | |
release("shoot_half") | |
repeat sleep(10) until (not get_shooting()) | |
steps = 1 | |
old_x = 0 | |
steps_back = 0 | |
inf = 81000 | |
function get_focus_distance_upper() -- returns focus distance in mm, but note 'accuracy' is 1cm from Canon. NOTE - NOT USED | |
local x = -1 | |
if (bi.platsub == "101a") then | |
x = peek(0x00244916, 2) | |
elseif (bi.platsub == "120f") then | |
x = peek(0x0024495A, 2) | |
else | |
error('Not 101a or 120f') | |
end | |
if x ~= -1 then return x*10 else return x end | |
end | |
function get_focus_distance_lower() -- returns focus distance in mm, but note 'accuracy' is 1cm from Canon | |
local x = -1 | |
if (bi.platsub == "101a") then | |
x = peek(0x00244918, 2) | |
elseif (bi.platsub == "120f") then | |
x = peek(0x0024495C, 2) | |
else | |
error('Not 101a or 120f') | |
end | |
if x == -1 then return -1 else return x*10 end | |
end | |
function refocus_to(xx) -- Only moves towards infinity. Returns requested focus distance in mm | |
local current_x = get_focus_distance_lower() -- current focus distance in mm to nearest cm. Based on Canon lower EXIF value | |
local steps_total = 0 | |
local last_step_count = steps_total | |
if xx < current_x then return -1 end -- don't use | |
local last_step_x = current_x | |
while current_x < xx do | |
call_event_proc("EFLensCom.MoveFocus", steps, 1) -- move smallest step you can towards infinity | |
steps_total = steps_total + steps | |
sleep(25) -- for system to catch up | |
current_x = get_focus_distance_lower() -- Get Canon lower EXIF value | |
if (current_x ~= last_step_x) and (current_x < xx) then -- just went through an intermediate step change, ie not yet reached the step that covers xx | |
last_step_x = current_x | |
last_step_count = steps_total -- close enough | |
end | |
end | |
-- now fine tune position backwards if required | |
steps_back = ((current_x - xx) * (steps_total - last_step_count)) / (current_x - last_step_x) | |
if steps_back > 0 then | |
for i = 1, steps_back do call_event_proc("EFLensCom.MoveFocus", -steps, 1) end | |
end | |
sleep(25) -- for system to catch up | |
current_x = get_focus_distance_lower() | |
return xx -- request focus position, eg the 'best' estimate in mm as to where we really are | |
end | |
function lens_name() | |
local get_lens_name_fn = 0xfc2f3fd5 | |
if (bi.platsub == "101a") then get_lens_name_fn = 0xfc2f3fc3 end | |
if call_event_proc('System.Create') == -1 then error('Unknown Error') end | |
local ppname = call_event_proc('AllocateMemory', 8) | |
if ppname == -1 or ppname == 0 then error('Unknown Error') end | |
local plen = ppname + 4 | |
poke(ppname, 0) | |
poke(plen, 0) | |
local status = call_func_ptr(get_lens_name_fn, ppname, plen) | |
local pname = peek(ppname) | |
local len = peek(plen) | |
call_event_proc('FreeMemory', ppname) | |
if ppname == -1 or ppname == 0 then error('Unknown Error') end | |
local i = 0 | |
local t = {} | |
while i < len do | |
local c = peek(pname + i, 1) | |
if c == 0 then break end | |
table.insert(t, string.char(c)) | |
i = i + 1 | |
end | |
local name = table.concat(t) | |
return name | |
end | |
function restore() | |
set_tv96_direct(s) | |
set_av96_direct(av) | |
press("shoot_half") | |
repeat sleep(10) until get_shooting() | |
sleep(100) | |
release("shoot_half") | |
repeat sleep(10) until (not get_shooting()) | |
if current_focus_mode ~= 1 then set_mf(0) end | |
if (current_mode ~= "M") then capmode.set(current_mode) end | |
set_lcd_display(1) | |
exit_alt() | |
print_screen(0) | |
cls() | |
end | |
function set_up() | |
current_focus_mode = get_focus_mode() | |
current_mode = capmode.get_name() | |
if current_focus_mode ~= 1 then set_mf(1) end | |
s = get_tv96() | |
av = get_av96() | |
press("shoot_half") | |
repeat sleep(10) until get_shooting() | |
if sky > 0 and bracket == 0 then -- reset exposure for the sky/infinity bracket | |
set_tv96_direct(s - 96*(sky+1)) | |
sleep(100) | |
end | |
if (current_mode ~= "M") then capmode.set("M") end | |
s = get_tv96() | |
set_tv96_direct(s) | |
set_av96_direct(av) | |
sleep(100) | |
release("shoot_half") | |
repeat sleep(10) until (not get_shooting()) | |
dof = get_dofinfo() | |
f = dof.focal_length -- in microns | |
F = f / 1000 -- focal length in mm | |
lens_test = lens_info() | |
hH() -- hyperfocal info | |
end | |
function myshoot() | |
local prevcnt = hook_shoot.count() | |
local rawprevcnt = hook_raw.count() | |
press 'shoot_full_only' | |
repeat sleep(10) until prevcnt ~= hook_shoot.count() | |
release 'shoot_full_only' | |
repeat sleep(10) until rawprevcnt ~= hook_raw.count() | |
end | |
function X_bracket() | |
press("shoot_half") | |
repeat sleep(10) until (get_shooting()) | |
set_tv96_direct(s) | |
if bracket == 0 or bracket >= 8 then | |
myshoot() | |
elseif bracket == 1 then | |
myshoot() | |
set_tv96_direct(s - 96 * 4) | |
myshoot() | |
elseif bracket == 2 then | |
myshoot() | |
set_tv96_direct(s - 96 * 3) | |
myshoot() | |
elseif bracket == 3 then | |
myshoot() | |
set_tv96_direct(s - 96 * 2) | |
myshoot() | |
elseif bracket == 4 then | |
myshoot() | |
set_tv96_direct(s - 96 * 2) | |
myshoot() | |
set_tv96_direct(s - 96 * 4) | |
myshoot() | |
elseif bracket == 5 then | |
myshoot() | |
set_tv96_direct(s - 96 * 2) | |
myshoot() | |
set_tv96_direct(s - 96 * 4) | |
myshoot() | |
set_tv96_direct(s - 96 * 6) | |
myshoot() | |
elseif bracket == 6 then | |
local iso = get_iso_mode() | |
set_iso_mode(100) | |
myshoot() | |
set_iso_mode(1600) | |
myshoot() | |
set_iso_mode(iso) | |
elseif bracket == 7 then | |
shot_histo_enable(1) | |
myshoot() | |
sleep(100) | |
lower = 1024 - 1024*hilit/100 | |
test=get_histo_range(lower,1024) | |
step = 0 | |
while test > 0 do | |
step = step + 1 | |
set_tv96_direct(s + 96 * 2 * step) | |
myshoot() | |
sleep(100) | |
test=get_histo_range(lower,1024) | |
end | |
shot_histo_enable(0) | |
end | |
set_tv96_direct(s) | |
release("shoot_half") | |
repeat sleep(10) until (not get_shooting()) | |
end | |
function bookend() | |
set_tv96_direct(960) | |
set_av96_direct(get_max_av96()) | |
local ecnt = get_exp_count() | |
shoot() | |
set_tv96_direct(s) | |
set_av96_direct(av) | |
repeat sleep(10) until (get_exp_count() ~= ecnt) | |
end | |
function hiatus() | |
local m = imath.mul(f,Mmax) | |
local temp = imath.mul(2000,Fmax) | |
temp = imath.mul(temp,Mmax)+Fmax | |
local temp2 = imath.mul(2000,f) | |
temp2 = imath.mul(temp2,Mmax) | |
temp = temp-temp2 | |
local m = imath.div(m,temp) -- Note this is an estimate of the mag at f, based on a simplified thin lens model that ignores extension at f, but not at Fmax | |
t = (F * (1000 + m) * (1000 + m)) | |
t = MFD - t / (1000 * m) -- this is an estimate of the spilt thin lens thickness (mm) | |
return t | |
end | |
function lens_info() | |
if lens_name() == "EF-M11-22mm f/4-5.6 IS STM" then -- calculate lens thickness from manufacturer's data | |
-- add other lenses as required, ie replace the following for your lens | |
-- For the above lens, 300 is the lens max magnification x 1000, ie from manufacturer's data or your measurement | |
-- 22000 is the lens maximun zoom, or the prime, focal length in microns | |
-- 150 is the lens minimum focus distance (mm), ie from manufacturer's data or your measurement | |
Fmax = 22000 -- Longest focal length (mm) * 1000 | |
Mmax = 300 -- Max magnification * 1000 | |
MFD = 150 -- Minimum Focus Distance in mm | |
t = hiatus() -- distance between front and rear principals in mm | |
return true | |
elseif lens_name() == "EF-M28mm f/3.5 MACRO IS STM" then | |
Fmax = 28000 -- Longest focal length (mm) * 1000 | |
Mmax = 1000 -- Max magnification * 1000 | |
MFD = 97 -- Minimum Focus Distance in mm | |
t = hiatus() -- distance between front and rear principals in mm | |
return true | |
elseif lens_name() == "EF-M55-200mm f/4.5-6.3 IS STM" then | |
Fmax = 200000 -- Longest focal length (mm) * 1000 | |
Mmax = 210 -- Max magnification * 1000 | |
MFD = 960 -- Minimum Focus Distance in mm | |
t = hiatus() -- distance between front and rear principals in mm | |
return true | |
elseif lens_name() == "EF-M18-55mm f/3.5-5.6 IS STM" then | |
Fmax = 55000 -- Longest focal length (mm) * 1000 | |
Mmax = 240 -- Max magnification * 1000 | |
MFD = 150 -- Minimum Focus Distance in mm | |
t = hiatus() -- distance between front and rear principals in mm | |
return true | |
elseif lens_name() == "EF-M15-45mm f/3.5-6.3 IS STM" then | |
Fmax = 45000 -- Longest focal length (mm) * 1000 | |
Mmax = 250 -- Max magnification * 1000 | |
MFD = 250 -- Minimum Focus Distance in mm | |
t = hiatus() -- distance between front and rear principals in mm | |
return true | |
--[[ | |
elseif lens_name() == "10-20mm" then | |
Fmax = 20000 -- Longest focal length (mm) * 1000 | |
Mmax = 130 -- Max magnification * 1000 | |
MFD = 240 -- Minimum Focus Distance in mm | |
t = hiatus() -- distance between front and rear principals in mm | |
return true | |
elseif lens_name() == "your lens" then | |
copy template above | |
]] | |
else -- lens not recognised, so don't use | |
return false | |
end | |
end | |
function update() | |
if x > inf then | |
temp1 = "=> INF" | |
elseif x >= 5000 then | |
temp1 = tostring(x/1000).."."..tostring(x/100-10*(x/1000)).."m" | |
elseif x >= 1000 then | |
temp1 = tostring(x/10).."cm" | |
else | |
temp1 = x.."mm" | |
end | |
u = x2u(x) -- estimate of focus distance from split thin lens front principal in mm | |
old_x = x | |
if x < inf then | |
local h2=h/1000 | |
ndof = F*F/(u-F) | |
ndof = ndof+(h2*(F-h2*pmag))/(pmag*(u+h2-F)) | |
ndof = ndof+(pmag*(2*F+h2+t)-F)/pmag | |
andof = ndof | |
if ndof > 1000 then ndof = tostring(ndof/10).."cm" else ndof = tostring(ndof).."mm" end | |
if u < H then | |
fdof = F*F/(u-F) | |
fdof = fdof-(h2*(F+h2*pmag))/(pmag*(u-h2-F)) | |
fdof = fdof+(pmag*(2*F-h2+t)-F)/pmag | |
afdof = fdof | |
if fdof <= 1000 then | |
fdof = tostring(fdof).."mm" | |
elseif fdof < 5000 then | |
fdof = tostring(fdof/10).."cm" | |
else | |
fdof = tostring(fdof/1000).."."..tostring(fdof/100-10*(fdof/1000)).."m" | |
end | |
num = (imath.div(1000*H,1000*u)+1000) | |
num = 1+(imath.div(num,2000)+500)/1000 | |
else | |
afdof = inf | |
fdof = "INF" | |
num = 1 | |
end | |
else | |
andof = H | |
if andof > 1000 then ndof = tostring(andof/10).."cm" else ndof = tostring(andof).."mm" end | |
afdof = inf | |
fdof = "INF" | |
num = 1 | |
end | |
inf_blur = (overlap*(H-F))/(u-F) | |
draw.replace(obj1,"rectf",0,0,lcd,35,"black","black") | |
if u < H then | |
temp = " <H : " | |
else | |
temp = " >=H : " | |
end | |
draw.replace(obj2,"string",(30*lcd)/720,0,temp..temp1,"white","black") | |
temp1 = F.."mm / #"..num | |
draw.replace(obj3,"string",(280*lcd)/720, 0,temp1,"white","black") | |
if dofs == 0 then | |
temp1 = ndof.." / "..inf_blur.."um" | |
else | |
temp1 = ndof.." / "..fdof | |
end | |
draw.replace(obj4,"string",(490*lcd)/720,0,temp1,"white","black") | |
if image and not get_alt_mode() and traf == 1 and last_image_u < inf then -- display traffic lights | |
local clr = "black" | |
if x == last_image_x then | |
clr = "yellow" | |
elseif (andof >= last_ndof) and (andof <= last_fdof) then | |
clr = "green" | |
elseif (andof > last_fdof) or (andof < last_ndof) then | |
clr = "red" | |
end | |
draw.replace(obj5,"rectf",5,5,20,25,clr,clr) -- update left traffic light | |
if x == last_image_x then | |
clr = "yellow" | |
elseif (afdof <= last_fdof) and (afdof >= last_ndof) then | |
clr = "green" | |
elseif (afdof > last_fdof) or (afdof < last_ndof) then | |
clr = "red" | |
end | |
draw.replace(obj6,"rectf",(700*lcd)/720,5,(715*lcd)/720,25,clr,clr) -- update right traffic light | |
temp1 = F.."mm / " | |
local ee = (f*(pmag-1))/(pmag*1000) -- pupil extension in mm, ie close enough | |
local blur = ee*(u+last_image_u)-2*u*last_image_u | |
blur = blur + F*(u+last_image_u-2*ee) | |
blur = (blur*(n/100))/10 | |
blur = (1000*F*F*(u-last_image_u))/blur | |
if blur < 0 then blur = -blur end | |
if x < inf then | |
temp1 = temp1..blur.."um" | |
else | |
temp1 = temp1.."???" | |
end | |
draw.replace(obj3,"string",(280*lcd)/720, 0,temp1,"white","black") | |
else | |
clr = "black" | |
draw.replace(obj5,"rectf",5,5,20,25,clr,clr) -- update left traffic light | |
draw.replace(obj6,"rectf",(700*lcd)/720,5,(715*lcd)/720,25,clr,clr) -- update right traffic light | |
end | |
draw.overdraw() | |
dirty = false | |
end | |
function refresh() | |
dirty = true | |
last_x = 0 | |
end | |
-- Main Section | |
set_up() | |
if lens_test == false then | |
print("Can only use registered EF-M lenses") | |
sleep(3000) | |
restore() | |
return | |
end | |
if bracket > 0 and sky > 0 then | |
print("Exposure bracketing clash!") | |
sleep(3000) | |
restore() | |
return | |
end | |
if lens == 1 then | |
print_screen(-1) | |
print(lens_name()) | |
restore() | |
return | |
end | |
if mode == 2 then -- move to focus minimum | |
repeat | |
x = get_focus_distance_lower() | |
call_event_proc("EFLensCom.FocusSearchNear") | |
sleep(50) | |
until x == get_focus_distance_lower() | |
end | |
print_screen(0) -- switch off logging until bracketing | |
last_x = 0 | |
dirty = true | |
lcd = 0 | |
if help == 0 then -- then switch off console display | |
set_console_layout(0,0,1,0) | |
print("") | |
set_console_autoredraw(-1) | |
end | |
-- Set up the bar drawing objects | |
obj1 = draw.add("rectf", 0, 0, 0, 0, "black","black") | |
obj2 = draw.add("string", 0, 0, "","white","black") | |
obj3 = draw.add("string", 0,0,"","white","black") | |
obj4 = draw.add("string",0,0,"","white","black") | |
obj5 = draw.add("rectf", 0, 0, 0, 0, "black","black") | |
obj6 = draw.add("rectf", 0, 0, 0, 0, "black","black") | |
last_alt_state = get_alt_mode() | |
image = false -- no image taken yet | |
last_ndof = 0 -- info from the last image taken | |
last_fdof = 0 | |
last_image_x = 0 | |
andof = 0 | |
afdof = 0 | |
ecnt = get_exp_count() | |
tsec = get_day_seconds() | |
repeat -- stay here while in asssess mode | |
x = get_focus_distance_lower() | |
if last_x ~= x then dirty = true end | |
last_x = x | |
wait_click(50) -- check for a button press | |
if is_key("right") and get_alt_mode() then -- re-run set up tasks | |
set_up() | |
refresh() | |
image = false | |
elseif is_key("shoot_full") and not get_alt_mode() then -- taking an image outside of ALT mode | |
last_ndof = andof | |
last_fdof = afdof | |
last_image_x = x | |
last_image_u = u | |
repeat sleep(50) until ecnt ~= (get_exp_count()) | |
ecnt = get_exp_count() | |
image = true | |
set_up() | |
refresh() | |
enter_alt() | |
exit_alt() | |
end | |
if is_key("shoot_half") and not get_alt_mode() then refresh() end -- redraws info bar if it disappears outside of ALT mode | |
if get_alt_mode() ~= last_alt_state then refresh() end -- refresh info bar | |
if ecnt ~= get_exp_count() then refresh() end | |
if get_gui_screen_width() ~= lcd then -- screens have changed | |
if get_gui_screen_width() == 720 then -- potentially show the console if requested | |
set_console_autoredraw(1) | |
set_console_layout(0,0,45,1) | |
refresh() | |
else -- don't show console when using EVF | |
set_console_autoredraw(-1) | |
set_console_layout(0,0,1,1) | |
print("") | |
refresh() | |
end | |
end | |
lcd = get_gui_screen_width() | |
last_alt_state = get_alt_mode() | |
if lcd == 720 and help == 1 then -- update console to show help reminder | |
print("SET=Run : RIGHT=Reset : FSP = EXIT") | |
end | |
if dirty and get_mode() then update() end -- only update the info bar if things have changed | |
sleep(500) -- no need to check too often | |
if (get_day_seconds()-tsec > 3) and x == last_x then | |
tsec = get_day_seconds() | |
refresh() | |
end | |
until ((is_key("set") or is_key("shoot_full")) and get_alt_mode()) -- then take brackets or exit | |
if help == 1 and lcd == 720 then -- show bracketing progress in main screen | |
set_console_autoredraw(1) | |
set_console_layout(0,0,45,1) | |
end | |
if log == 1 then | |
set_console_autoredraw(-1) | |
print_screen(-1) | |
print("...") | |
print(os.date()) | |
set_console_autoredraw(1) | |
end | |
t1=os.time() -- start the clock | |
draw.clear() | |
print_screen(0) | |
print("Bracketing Started") | |
if log == 1 then print_screen(-1) end -- switch focus bracketing logging on | |
u = x2u(x) -- estimate of focus distance from split thin lens front principal in mm | |
old_x = x | |
if bookends == 1 then bookend() end | |
t1=sleep_time-(os.time()-t1) | |
if t1 > 0 then sleep(t1*1000) end | |
if screen_off == 1 then set_lcd_display(0) end | |
if x >= 1000 then | |
temp = x/10 | |
print("1/"..num.." @ "..temp.."cm") | |
else | |
print("1/"..num.." @ "..x.."mm") | |
end | |
X_bracket() -- First exposure(s) | |
if mode == 0 then -- exposure bracket only requested so exit script after taking images at current focus | |
if sky > 0 and bracket == 0 then -- sky bracket requested | |
press("shoot_half") | |
repeat sleep(10) until (get_shooting()) | |
set_tv96_direct(s + 96*(sky+1)) | |
myshoot() | |
set_tv96_direct(s) | |
release("shoot_half") | |
repeat sleep(10) until (not get_shooting()) | |
end | |
if bookends == 1 then bookend() end | |
restore() | |
return | |
end | |
i = 1 | |
while (u < H/3) do -- capture the rest of the focus brackets up to H/3 | |
-- Note that focus bracketing is calculated/updated in u space, but actual refocusing is in x space | |
-- All console feedback is in x space, ie distances measured from the sensor | |
new_u = 2*F*F*(pmag-1) + F*(u-2*pmag*u) + (h/1000)*pmag*u | |
new_u = new_u/( F*(2*pmag-1) + pmag*(h/1000-2*u) ) -- new u in mm, using DOFIS model | |
if new_u <= u then new_u = u + 5 end -- move at least 5mm, just in case. Remember: script is not designed for macro work! | |
u = new_u | |
x = (1000*u + f + (f*f)/(1000*u-f) + 1000*t) / 1000 -- next focus bracket estimate in x space: in mm from f(1+m)+t+u | |
refocus_to(x) | |
old_x = x | |
i = i + 1 | |
if x >= 1000 then | |
temp = x/10 | |
print(i.."/"..num.." @ "..temp.."cm") | |
else | |
print(i.."/"..num.." @ "..x.."mm") | |
end | |
X_bracket() | |
end | |
if u < inf and x < inf then -- take additional images beyond H | |
if u < H then | |
refocus_to((F*F)/(H-F) + F + t + H) | |
temp = (F*F)/(H-F) + F + t + H | |
else | |
temp = (F*F)/(u-F) + F + t + u | |
end | |
print("@H = "..temp/10 .."cm") | |
X_bracket() | |
temp = (F*F)/(infinity*H-F) + F + t + infinity*H | |
if temp > inf then -- adjust | |
repeat | |
infinity = infinity - 1 | |
temp = (F*F)/(infinity*H-F) + F + t + infinity*H | |
until temp < inf or infinity == 2 | |
end | |
refocus_to(temp) | |
print("@"..infinity.."H = ".. temp/10 .. "cm") | |
X_bracket() | |
if sky > 0 and bracket == 0 then -- take an extra exposure shot for the sky | |
press("shoot_half") | |
repeat sleep(10) until (get_shooting()) | |
set_tv96_direct(s + 96*(sky+1)) | |
myshoot() | |
set_tv96_direct(s) | |
release("shoot_half") | |
repeat sleep(10) until (not get_shooting()) | |
print("Inf X @ ".. temp/10 .."cm") | |
end | |
end | |
if bookends == 1 then bookend() end | |
restore() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment