Skip to content

Instantly share code, notes, and snippets.

@pigeonhill pigeonhill/lbs.lua
Last active Mar 2, 2019

Embed
What would you like to do?
CHDK Landscape Bracketing
--[[
@title Landscape Bracketing
'Perfect' focus brackets from near to blur defined 'infinity': overlap defined at a fraction of camera's CoC
Plus option of two additional exposure brackets at each focus step, at 1Ev, 2Ev or 3Ev using -/+ or -/-- or +/++ logic
More info at https://chdk.wikia.com/wiki/Landscape_Focus_Bracketing_:_perfect_near_to_far_focus_brackets
Camera should be in manual focus mode and M mode
Release 1.9985
Tested on a G7X & G1X
(c) Garry George
@chdk_version 1.5
@param u Focus stack mode?
@default u 0
@values u X2Inf Mac2Inf Mac2X X2delX
@param g Overlap at?
@default g 3
@values g CoC 2CoC/3 CoC/2 diff
@param p Exposure bracket delta?
@default p 0
@values p None 1Ev 2Ev 3Ev 800 1600 ZN
@param j Exposure bracket logic?
@default j 0
@values j 0/-/+ 0/-/-- 0/+/++
@param m Delta from X (mm)
@default m 25
@range m 1 200
@param n Max number of focus brackets?
@default n 0
@values n Inf <10 <20 <30
@param c Script Delay (s)
@default c 3
@range c 0 5
@param b Bookends?
@default b 1
@values b No Yes
@param q Infinity focus quality?
@default q 1
@values q CoC/2 CoC/3 CoC/4
@param v Show bracket pos?
@default v 1
@values v No Yes
@param k Log?
@default k 0
@values k No Yes
@param e Delete Log File?
@default e 0
@values e No Yes
--]]
capmode = require("capmode")
if (capmode.get_name() ~= "M") then
print("Switch to M mode")
return -- exit script
end
if get_focus_mode() ~= 1 then
print("Switch to MF mode")
return -- exit script
end
if e == 1 then
local fp = io.open("A/CHDK/DATA/LBS.CFG")
local str = fp:read("*all")
fp:close()
temp = string.sub(str, 1, 1)
temp = "A/CHDK/DATA/LBS."..temp
fp = io.open (temp,"r")
if fp == nil then
print("No ConFig file found")
return
else
str = fp:read("*all")
fp:close()
if string.find(str,"e=0") == nil then
str = string.gsub(str,"#e=1","#e=0")
fp = io.open (temp,"w")
fp:write(str)
fp:close()
os.remove("A/CHDK/LOGS/LOG_2306.TXT")
print("Log File Deleted")
return -- exit script
end
end
end
if (get_focus() == -1) then
print("@ Infinity")
return -- exit script
end
press("shoot_half") -- get current exposure
t = get_tick_count()
repeat
sleep(50)
if get_tick_count() - t > 5000 then
print("Unknown Error")
release("shoot_half")
return
end
until (get_shooting() == true)
release("shoot_half")
s = get_tv96()
av = get_av96()
dof = get_dofinfo()
x = dof.focus
x_start = x
last_x = x
base_h = dof.hyp_dist
temp = 0
temp1 = 0
temp2 = 0
ok = true
fl = dof.focal_length/100
log = {}
count = 0
ecnt = get_exp_count()
if u == 1 or u == 2 then -- change focus to min focus
set_focus((4*fl)/10)
press("shoot_half")
repeat
x = get_focus()
sleep(100) -- seems to work on G7X & G1X, may need changing on other cams
until x == get_focus()
release("shoot_half")
end
-- A few Functions
function myshoot()
ecnt = get_exp_count()
shoot()
end
function bookend()
if b == 1 then
set_tv96(960)
set_av96(640)
myshoot()
set_tv96_direct(s)
set_av96_direct(av)
repeat sleep(20) until(get_exp_count()~=ecnt)
end
end
function refocus(xx)
local dis = 0
set_focus(xx)
press("shoot_half")
repeat
dis = get_focus()
sleep(200) -- seems to work on G7X & G1X, may need changing on other cams
until dis == get_focus()
release("shoot_half")
end
function X_bracket()
set_tv96_direct(s)
count = count + 1
if p == 0 then
myshoot()
elseif p < 4 and j == 0 then
myshoot()
set_tv96_direct(s-96*p)
myshoot()
set_tv96_direct(s+96*p)
myshoot()
elseif p < 4 and j == 1 then
myshoot()
set_tv96_direct(s+96*p)
myshoot()
set_tv96_direct(s+2*96*p)
myshoot()
elseif p < 4 and j == 2 then
myshoot()
set_tv96_direct(s-96*p)
myshoot()
set_tv96_direct(s-2*96*p)
myshoot()
elseif p == 4 then
local iso = get_sv96()
set_sv96(sv96_market_to_real(iso_to_sv96(100)))
myshoot()
set_sv96(sv96_market_to_real(iso_to_sv96(800)))
myshoot()
set_sv96(iso)
elseif p == 5 then
local iso = get_sv96()
set_sv96(sv96_market_to_real(iso_to_sv96(100)))
myshoot()
set_sv96(sv96_market_to_real(iso_to_sv96(1600)))
myshoot()
set_sv96(iso)
elseif p == 6 then
myshoot()
set_tv96_direct(s-96*4)
myshoot()
end
set_tv96_direct(s)
end
h = base_h -- no overlap case: brackets 'touch' at CHDK CoC
if g == 1 then -- adjust h to achieve the requested overlap, ie 'touching' at 2*CoC/3 or CoC/2 or at the diffraction aware defocus blur
h = (h*3)/2
elseif g == 2 then
h = 2*h
elseif g == 3 then -- use diffraction aware overlap: Assume CHDK CoC is total blur, formed in quadrature from defocus and diffraction blurs
temp1 = 1000*dof.coc -- total blur set up for imath
temp2 = (1342*dof.aperture)/1000 -- set up for imath. From diff_blur = 2.44*0.55*N (um)
if temp1 > temp2 then -- can use diffraction aware overlap
temp = imath.sqrt(imath.mul(temp1,temp1) - imath.mul(temp2,temp2)) -- diffraction aware defocus blur
temp2 = imath.div(temp1,temp)
if temp2 > 3000 then
h = 3*h
print("Warning: High Diff: using CoC/3")
else
h = (h*temp2)/1000
end
else -- diff blur > total blur
h = 3*h
print("Warning: Diff>Defocus: using CoC/3")
end
end
if (x > base_h or x == -1) then
print("@/beyond H")
sleep(c*1000)
bookend()
X_bracket()
temp = get_exp_count().." @ "..x_start.."mm"
if v == 1 then print(temp) end
bookend()
return -- exit script
else
num = ((10*(h + x))/(2*x) + 5)/10
end
if u == 2 or u == 3 then
dof = get_dofinfo()
x = dof.focus -- register actual x
last_x = x
sleep(c*1000)
bookend()
if u == 3 then x_start = x_start+m end
repeat -- to capture focus brackets from min focus up to x
X_bracket()
temp = get_exp_count().." @ "..x.."mm"
if v == 1 then print(temp) end
x = (x*(h*10 - 2*fl))/(h*10 - 2*x*10) -- position of next focus bracket
if (x - last_x) == 0 then x = last_x + 1 end
if x < last_x or x <= 0 then
print("Unknown Error")
refocus(x_start)
return
end
refocus(x) -- request move to x
dof = get_dofinfo()
x = dof.focus -- register actual x moved by cam
last_x = x
until (x > x_start)
refocus(x_start)
dof = get_dofinfo()
x = dof.focus -- register actual x moved by cam
X_bracket()
bookend()
temp = get_exp_count().." @ "..x.."mm"
if v == 1 then print(temp) end
return -- exit script
end
if (n ~= 0 and num > (n*10)-1) then -- accounting for last bracket at infinity focus
print("Warning")
temp2 = num + 1
print("Focus Steps = "..temp2)
return -- exit script
end
sleep(c*1000)
bookend()
-- else look after u == 0 or 1 cases
refocus(x) -- explicitly refocus to start
dof = get_dofinfo()
x = dof.focus
last_x = x
if k == 1 then log[#log + 1] = "\n"..os.date() end
X_bracket()
temp = get_exp_count().." @ "..x.."mm"
if v == 1 then print(temp) end
if k == 1 then log[#log + 1] = temp end
repeat -- to capture focus brackets up to just past h/3
x = (x*(h*10 - 2*fl))/(h*10 - 2*x*10) -- position of next focus bracket
if x <= last_x or x <= 0 then
print("Unknown Error")
refocus(x_start)
return
end
refocus(x) -- request move to x
dof = get_dofinfo()
x = dof.focus -- register actual x moved by cam
last_x = x
X_bracket()
temp = get_exp_count().." @ "..x.."mm"
if v == 1 then print(temp) end
if k == 1 then log[#log + 1] = temp end
until (x > h/3)
temp1 = h
temp2 = base_h*(q+2)
refocus(temp1) -- take shot at h
X_bracket()
temp = get_exp_count().." @ "..temp1.."mm"
if v == 1 then print(temp) end
if k == 1 then log[#log + 1] = temp end
if temp2 > temp1 then -- take additional infinity focus shot
refocus(temp2)
X_bracket()
temp = get_exp_count().." @ "..temp2.."mm"
if v == 1 then print(temp) end
if k == 1 then log[#log + 1] = temp end
end
bookend()
temp = count.." focus brackets"
print(temp)
if k == 1 then log[#log + 1] = temp end
temp1 = ((10*dof.coc*base_h)/temp2 + 5)/10
temp = "Infinity blur "..temp1.."um"
if k == 1 then log[#log + 1] = temp end
if p ~= 0 and k == 1 then log[#log + 1] = "Exposure offset = "..p.."Ev" end
refocus(x_start)
if k == 1 then
print_screen(-2306)
for i = 1, #log do
print(log[i].."\n")
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.