Could this be the 'ultimate' bracketing script?

Started by garry23, May 28, 2016, 09:32:13 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

garry23

As some will be aware, I have been putting some effort into writing a bracketing script for (non-macro) focus bracketing.

In this post I offer my latest version for testing and feedback.

I have tried to make the script 'robust' and have built in some error checking (but still read the comments at the start of the script).

The script will automatically do the following things:

  • Take a set of focus brackets from near to infinity
  • Take a set of exposure brackets from the user set shadow end exposure (hint use ML's RAW spotmeter), to the ETTR position
  • Take exposure and focus bracket sets together
  • Take a set of same exposure brackets, ie to simulate a longer ND time
  • Take a set of same exposure brackets, eg for post processing for super-res or eliminating people

The usual caveats apply, ie I wrote the script for my use and to run on my 5D3 with my lenses. However, I'm confident it should run on any non-EOSM camera that runs the ML Lua module. Note the lens must report AF.

Finally, I really would welcome feedback from others, ie to help me in my efforts and to make the script better.

Cheers

Garry

UPDATED: 29th May 2016

--[[
Auto Bracketing Script
Auto focus bracketing with exposure bracketing
Plus the script does both time and frame bracketing, ie for LE situations
Release 0.95
This version has some error detection, but the user must be aware of certain things:
* Check the correct DoF diffraction options are set in ML, eg diffraction aware is on for best data
* Must use a lens that reports focus distance and DoF can be calculated
* Lens must be in AF mode
* Must be in manual mode
* Switch stabalisation off as you will not be hand holding ;-)
* Must be in LV mode: script won't run unless in LV
* ETTR ON: settings recommended are - no link to dual, SNRs to OFF, highlights very low or zero (your choice_, and not Always On or Auto Snap
* as this may 'confuse' the script
* You can switch focus bracketing on/off in the menu, ie use LE and/or exposure mode alone. The script handles the logic, ie if LE mode is being used,
* then you can't use focus or exposure bracketing
* Image review must not be set to HOLD in Canon menu
* Assumes lens is focused at nearest point to start a focus stack, ie script moves to infinity
* Script takes last bracket with focus point at infinity
* When exposure bracketing, set base exposure to capture shadows (the script will calculate the ETTR of the scene)
* If ETTR fails, then try adjusting ETTR set time to give your camera more time (or experiment with less)
* Final thought: photography should be relaxing, hence I personally don't mind that this script takes time to run. As it's
* running, look around you and enjoy nature and the moment :-)
*******************************************************************************************************
*   *
* If you reference this script, please consider acknowledging me at http://photography.grayheron.net/ *
*   *
*******************************************************************************************************
--]]

-- Declare a few variables for the script whick load when camera switced on
a1 = 0
b1 = 0
a2 = 0
b2 = 0
fp = 0
inf = 100000
base_tv = 0
delay = 0
factor = 0
num_brackets = 0
ETTR_tv = 0
base_tv = 0
user_tv = 0
LE_brackets = 0
running = false
no_tv_error = true
brackets_requested = false
flash = true

function reset()  -- tidy up at the end
no_tv_error = true
brackets_requested = false
running = true
display.notify_box("***FINISHED***",4000)
beep (3, 200 , 1000)  -- notify end of script
display.clear()
end

function my_shoot()
if camera.shutter.apex < -4 then
camera.bulb(camera.shutter.value)
else
camera.shoot(64, false)
end
end

function check_bookend()
if keymenu.submenu["Bookends?"].value == "yes"
then
local tv = camera.shutter.ms
local av = camera.aperture.value
camera.shutter.ms = 1
camera.aperture.apex = 9
my_shoot()
camera.shutter.ms = tv
camera.aperture.value = av
end
end

function find_ETTR()
-- Find the ETTR shutter value: make sure you have set ML ETTR values correctly
local m = menu.get("Auto ETTR","Trigger mode")
menu.set("Auto ETTR","Trigger mode",0) -- set ETTR menu to get an ETTR exposure
local check_tv = 0
repeat -- hang around until ETTR value has stabilised
check_tv = camera.shutter.apex
msleep (keymenu.submenu["ETTR Set Time?"].value*1000)  -- adjust this for your camera. The time delay allows the ML ETTR process to settle down
until check_tv == camera.shutter.apex
ETTR_tv = camera.shutter.apex
menu.set("Auto ETTR","Trigger mode",m) -- reset to user ETTR menu setting
if ETTR_tv < base_tv
then -- base TV needs resetting
display.notify_box("Warning Shadow Tv < ETTR Tv",4000)
beep (3, 200 , 500)  -- warning message
no_tv_error = false
end
end

function calc_brackets()
if no_tv_error then
num_brackets = (ETTR_tv - base_tv)/factor
num_brackets = math.floor(math.abs(num_brackets))
if num_brackets <= 1 then num_brackets = 1 end
end
end

function check_LE()
-- Check to see if user has requested LE bracketing of some kind
if keymenu.submenu["LE mode?"].submenu["select"].value ~= 0
then
if keymenu.submenu["LE mode?"].submenu["Mode?"].value == "time"
then
LE_brackets = math.ceil(keymenu.submenu["LE mode?"].submenu["select"].value/camera.shutter.value)
else
LE_brackets = keymenu.submenu["LE mode?"].submenu["select"].value
end
brackets_requested = true
end
end

function take_brackets()
local i
if LE_brackets == 0
then
if no_tv_error and brackets_requested then -- take exposure brackets
camera.shutter.apex = ETTR_tv
my_shoot()
for i = 1, num_brackets , 1
do
camera.shutter.apex = camera.shutter.apex - factor
my_shoot()
end
if camera.shutter.apex > base_tv
then
camera.shutter.apex = base_tv
my_shoot()
end
else -- take a single image
camera.shutter.apex = base_tv
my_shoot()
end
else -- take some LE bracketing images
for i = 1, LE_brackets , 1
do
my_shoot()
end
-- if no_tv_error then check_bookend() end
end
end

function albs()
if brackets_requested and keymenu.submenu["LE mode?"].submenu["select"].value == 0 then
find_ETTR()
calc_brackets() -- number of exposure brackets
else
msleep(delay)
end
if no_tv_error then check_bookend() end
-- Get DoF info & take first(only) exposure(s)
a2 = lens.dof_near
b2 = lens.dof_far
if no_tv_error then take_brackets() end
-- take focus brackets to infinity if requested
if keymenu.submenu["Focus bracketing?"].value == "yes"
then -- do focus bracketing
if lens.focus_distance < inf and no_tv_error then
repeat
a1=a2
b1=b2
repeat
lens.focus(-1,1)
b2 = lens.dof_far
a2 = lens.dof_near
fp = lens.focus_distance
until a2 > b1 or fp >= inf
lens.focus(1,1) -- move back one step for focus bracket overlap
take_brackets()
until fp >= inf
end
end
if no_tv_error then check_bookend() end
reset()  -- do some tiding up beforing exiting
end

function setup() -- does some checking before calling the main function
menu.close()
factor = tonumber(keymenu.submenu["Ev bracket delta per image"].value) -- set exposure bracketing offset (0, 1 or 2)
if not lv.enabled then lv.start() end -- just in case
if camera.model_short == "EOSM" then
display.notify_box("Sorry doesn't work with the EOSM", 3000)
else
check_LE()
if factor ~= 0 then brackets_requested = true else brackets_requested = false end
if running -- then script has already been used since camera switched on
then -- reset some stuff...just to be sure :-)
no_tv_error = true
end
if lens.focus_distance ~= 0 and lens.af -- lens is OK
then -- fit to run the main function
base_tv = camera.shutter.apex
albs() 
else  -- lens not OK!
beep (3, 200 , 500)  -- warning message
display.notify_box("Check your lens", 5000)
end
end
end

keymenu = menu.new
{
    parent = "Shoot", -- change this to position the script into other ML menu locations
    name = "Auto Bracketing",
    help = "Remember: LV, DoF & AF on",
depends_on = DEPENDS_ON.LIVEVIEW,
warning = function(this)
if menu.get("Expo","Auto ETTR") == 0 then return "ETTR switched off" end
end,
    submenu =
{
{
name = "Run Script",
help = "Does what it says after pressing SET",
warning = function(this)
flash = not flash
if not lv.enabled then return "LV not enabled" end
end,
select = function(this)
if menu.get("Expo","Auto ETTR") ~= 0 and lv.enabled then
task.create(setup)
end
end,
},
{
name = "Focus bracketing?",
help = "Switches focus bracketing mode on/off",
choices = {"no","yes"},
update = function(this)
if keymenu.submenu["LE mode?"].submenu["select"].value ~= 0 then
menu.set("Auto Bracketing","Focus bracketing?",0)
end
end,
warning = function(this)
flash = not flash
if keymenu.submenu["LE mode?"].submenu["select"].value ~= 0 then
if flash then
return "LE mode on"
else
return ""
end
end
end,
},
{
name = "Ev bracket delta per image",
help = "0 = no auto exposure bracketing",
min = 0,
max = 2,
update = function(this)
if keymenu.submenu["LE mode?"].submenu["select"].value ~= 0 then
menu.set("Auto Bracketing","Ev bracket delta per image",0) end
end,
warning = function(this)
if keymenu.submenu["LE mode?"].submenu["select"].value ~= 0 then
if flash then
return "LE mode on"
else
return ""
end
end
end
},
{
name = "LE mode?",
rinfo = function(this)
if keymenu.submenu["LE mode?"].submenu["select"].value == 0
then return "off"
else return "active"
end
end,
help = "In seconds or frames. Zero = no LE bracketing",
halp2 = "LE or frame bracketing trumps all other bracketing modes",
           submenu =
            {
                {
name = "select",
min = 0,
max = 120,
rinfo = function(this)
if keymenu.submenu["LE mode?"].submenu["Mode?"].value == "time" then return "secs" else return "frames" end
end,
update = function(this)
if keymenu.submenu["LE mode?"].submenu["select"].value ~= 0 then
menu.set("Auto Bracketing","Ev bracket delta per image",0)
menu.set("Auto Bracketing","Focus bracketing?",0)
end
end,
warning = function(this)
if keymenu.submenu["LE mode?"].submenu["Mode?"].value == "time" then
LE_brackets = math.ceil(keymenu.submenu["LE mode?"].submenu["select"].value/camera.shutter.value)
if LE_brackets == 0 then
return "LE bracket taking switched off"
else
return "Note: "..tostring(LE_brackets).." brackets will be taken"
end
end
end
                },
                {
name = "Mode?",
choices = {"time","# frames"},
help = "In seconds or #frames. Zero = no LE bracketing",
                }
            }
        },
{
name = "Bookends?",
help = "Places a dark frame at start and end of focus bracket set",
choices = {"no","yes"},
},
{
name = "Delay",
help = "Delays script start by stated number of secs",
choices = {"2","5","0"},
update = function(this)
delay = tonumber(keymenu.submenu["Delay"].value)*1000 -- delay in ms
end,
},
{
name = "ETTR Set Time?",
help = "A camera specific variable in seconds",
help2 = "Only change if ETTR fails to find a solution",
min = 2,
max = 8,
value = 4 -- set this to time that works in your camera
}
}
}