Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Get Brackets (CHDK)
--[[
@title Get Brackets
Capture 'Perfect' focus brackets, with focus overlap defined in terms of defocus (CHDK Circle of Confusion (CoC)) blur
Plus option of additional exposure brackets at each focus step, using various logic: 1Ev, 2Ev or 3Ev using -/+ or -/-- or +/++; one iso-invariant at
ISO at 800 or 1600; or one (Zero Noise) exposure at 4Ev, 3Ev or 2Ev
Focus bracketing strategies are: current position to blur-defined infinity (X2Inf); min camera focus to current position (Min2X), min camera focus to blur-defined infinity (Min2Inf);
current position to a delta x ahead of the current position (X2DelX); from a delta x in front of the current position to the current position (-DelX2X);
from a delta x in front of the current position to a delta x ahead of the current position (-D2+D).
None means that requested exposures will only be captured at the current focus point
Overlap, ie bracket to bracket focus insurance, is definded in terms of the defocus (CoC) blur, eg CoC/2 means focus brackets 'touch' at a blur of CoC/2.
Where as diff means that the defocus blur and the diffraction blur, taken in quadrature, equals the CHDK CoC value
Unless, under focus strategy, none is selected or the delX option is selected the script will take three focus brackets, even if initial focus is beyond the defocus hyperfocal (H),
ie at H/3, at H and at the blur-based infinity, which means DoF will go from H/4 to infinity. Thus focusing is not critical, just ensure focus is beyond H (+ have CHDK show focus & H)
Use Bookends to help differentiate bracket set in post
Option to switch LCD screen off during shooting
Rev 1.5
June 2019
Tested on a G7X ad G1X
Garry George
@chdk_version 1.5
# focus_strat = 0 "Focus logic?" {X2Inf Min2X Min2Inf X2DelX -DelX2X None -D2+D}
# overlap = 0 "Overlap at" {CoC 2CoC/3 CoC/2 diff}
# quality = 2 "Infinity quality?" {CoC/2 CoC/3 CoC/4}
# delx = 10 "Focus delta (mm)" [5 100]
# delta = 0 "Exposure delta?" {None 1Ev 2Ev 3Ev 800 1600 ZN4 ZN3 ZN2}
# logic = 0 "Exposure logic?" {0/-/+ 0/-/-- 0/+/++}
# delay = 3 "Script Delay (s)" [0 5]
# bookends = 1 "Bookends?" {No Yes}
# screen_off = 1 "Screen off?" {No Yes}
--]]
capmode = require("capmode")
function restore()
if x_start == -1 then refocus(1000000) else refocus(x_start) end
set_tv96_direct(s)
set_av96_direct(av)
press("shoot_half")
repeat sleep(10) until get_shooting()
sleep(1000)
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()
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
dof = get_dofinfo()
x = dof.focus
x_start = x
last_x = x
base_h = dof.hyp_dist -- that is without diffraction accounted for
fl = dof.focal_length/100
s = get_tv96()
av = get_av96()
if (current_mode ~= "M") then
capmode.set("M")
end
set_tv96_direct(s)
set_av96_direct(av)
press("shoot_half")
repeat sleep(10) until get_shooting()
sleep(1000)
release("shoot_half")
repeat sleep(10) until (not get_shooting())
return true
end
function myshoot() -- works inside X_bracket function
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 bookend()
set_tv96_direct(960)
set_av96_direct(640)
local ecnt = get_exp_count()
shoot()
set_tv96_direct(s)
set_av96_direct(av)
repeat sleep(10) until (get_exp_count() ~= ecnt)
end
function refocus(xx)
set_focus(xx)
dof = get_dofinfo() -- update info
end
function X_bracket()
press("shoot_half")
repeat sleep(10) until (get_shooting())
set_tv96_direct(s)
if delta == 0 then
myshoot()
elseif delta < 4 and logic == 0 then
myshoot()
set_tv96_direct(s-96*delta)
myshoot()
set_tv96_direct(s+96*delta)
myshoot()
elseif delta < 4 and logic == 1 then
myshoot()
set_tv96_direct(s+96*delta)
myshoot()
set_tv96_direct(s+2*96*delta)
myshoot()
elseif delta < 4 and logic == 2 then
myshoot()
set_tv96_direct(s-96*delta)
myshoot()
set_tv96_direct(s-2*96*delta)
myshoot()
elseif delta == 4 then
local iso = get_sv96()
myshoot()
set_sv96(sv96_market_to_real(iso_to_sv96(800)))
myshoot()
set_sv96(iso)
elseif delta == 5 then
local iso = get_sv96()
myshoot()
set_sv96(sv96_market_to_real(iso_to_sv96(1600)))
myshoot()
set_sv96(iso)
elseif delta == 6 then
myshoot()
set_tv96_direct(s-96*4)
myshoot()
elseif delta == 7 then
myshoot()
set_tv96_direct(s-96*3)
myshoot()
elseif delta == 8 then
myshoot()
set_tv96_direct(s-96*2)
myshoot()
end
set_tv96_direct(s)
release("shoot_half")
repeat sleep(10) until (not get_shooting())
end
-- Main section
if not set_up() then -- at the moment set_up() always returns true ;-)
restore()
return -- exit script
end
if screen_off == 1 then set_lcd_display(0) end
h = base_h -- no overlap case: brackets 'touch' at CHDK CoC
if overlap == 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 overlap == 2 then
h = 2*h
elseif overlap == 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
else
h = (h*temp2)/1000
end
else -- diff blur > total blur
h = 3*h
end
end
sleep(delay*1000)
if bookends == 1 then bookend() end
if x > base_h then focus_strat = 5 end
x_stop = h/3
if x == -1 then
-- skip the other checks
elseif focus_strat == 1 then
x = 0
x_stop = x_start
elseif focus_strat == 2 then
x = 0
elseif focus_strat == 3 then
x_stop = x_start + delx
elseif focus_strat == 4 then
x = x_start - delx
x_stop = x_start
elseif focus_strat == 5 then
x_stop = x_start
elseif focus_strat == 6 then
x_stop = x_start + delx
x = x_start - delx
end
while (x < x_stop) and focus_strat ~= 5 and x_start ~= -1 do -- capture the focus brackets up to the required x_stop
refocus(x)
X_bracket()
x = dof.focus -- get actual x moved by cam
last_x = x
x = (x*(h*10 - 2*fl))/(h*10 - 2*x*10) -- position of next focus bracket
if x <= last_x then -- likely because at macro end so get a new estimate of next x to get things going again
x = last_x + (x*x*dof.aperture*dof.coc)/(fl*fl*10000)
if x == last_x then x = last_x + 1 end
end
end
if x ~= x_stop then refocus(x_stop) end
X_bracket()
if focus_strat == 0 or focus_strat == 2 then
refocus(h) -- take shot at h
X_bracket()
temp2 = h*(quality+2)
refocus(temp2) -- take shoot at infinity blur quality
X_bracket()
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
You can’t perform that action at this time.