Last active
June 5, 2016 21:58
-
-
Save pigeonhill/750536059c927edaa55b34a6236ae8e1 to your computer and use it in GitHub Desktop.
Magic Lantern Bracketing Script
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
--[[ | |
Auto Bracketing Script | |
Auto focus bracketing with exposure bracketing | |
Plus the script does both time and frame bracketing, ie for LE situations | |
Release 1.0 | |
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 | |
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 | |
-- Before finishing the script, check if LE extras asked for | |
if keymenu.submenu["LE mode?"].submenu["select"].value ~= 0 and keymenu.submenu["LE mode?"].submenu["Plus"].value == "Dual-ISO" then | |
menu.set("Expo","Dual ISO",1) | |
task.yield(500) | |
my_shoot() | |
menu.set("Expo","Dual ISO",0) | |
elseif keymenu.submenu["LE mode?"].submenu["select"].value ~= 0 and keymenu.submenu["LE mode?"].submenu["Plus"].value == "Auto Bracketing" then | |
menu.set("Shoot","Advanced Bracket",1) | |
task.yield(500) | |
my_shoot() | |
menu.set("Shoot","Advanced Bracket",0) | |
end | |
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 | |
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(keymenu.submenu["Script delay"].value*1000) -- delay in ms | |
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: set 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) | |
if not lv.enabled then return "LV not enabled" end | |
if menu.get("Expo","Auto ETTR") == 0 then return "ETTR switched off" end | |
end, | |
select = function(this) | |
if menu.get("Expo","Auto ETTR") ~= 0 and lv.enabled and key.last == KEY.SET then task.create(setup) end | |
end | |
}, | |
{ | |
name = "Focus bracketing?", | |
help = "Switches focus bracketing mode on/off", | |
choices = {"no","yes"}, | |
icon_type = ICON_TYPE.BOOL, | |
warning = function(this) | |
if keymenu.submenu["LE mode?"].submenu["select"].value ~= 0 then | |
menu.set("Auto Bracketing","Focus bracketing?",0) | |
return "LE mode on" | |
end | |
end | |
}, | |
{ | |
name = "Ev bracket delta per image", | |
help = "0 = no auto exposure bracketing", | |
min = 0, | |
max = 2, | |
icon_type = ICON_TYPE.BOOL, | |
warning = function(this) | |
if keymenu.submenu["LE mode?"].submenu["select"].value ~= 0 then | |
menu.set("Auto Bracketing","Ev bracket delta per image",0) | |
return "LE mode on" | |
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", | |
help2 = "LE or frame bracketing trumps all other bracketing modes", | |
submenu = | |
{ | |
{ | |
name = "select", | |
min = 0, | |
max = 300, | |
icon_type = ICON_TYPE.BOOL, | |
rinfo = function(this) | |
if keymenu.submenu["LE mode?"].submenu["Mode?"].value == "time" then return "secs" else return "frames" end | |
end, | |
select = function(this,delta) | |
this.value = this.value + delta | |
if this.value > this.max then | |
this.value = this.min | |
elseif this.value < this.min then | |
this.value = this.max | |
end | |
if this.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 = "Plus", | |
icon_type = ICON_TYPE.BOOL, | |
choices = {"Nothing","Dual-ISO","Auto Bracketing"}, | |
help = "Takes an addition image or images, on top of the LE sequence" | |
} | |
} | |
}, | |
{ | |
name = "Bookends?", | |
help = "Places a dark frame at start and end of focus bracket set", | |
choices = {"no","yes"}, | |
icon_type = ICON_TYPE.BOOL, | |
}, | |
{ | |
name = "Script delay", | |
help = "Delays script start by stated number of secs", | |
min = 0, | |
max = 5, | |
icon_type = ICON_TYPE.BOOL, | |
select = function(this,delta) | |
if this.value == 0 then | |
this.value = 2 | |
elseif this.value == 2 then | |
this.value = 5 | |
elseif this.value == 5 then | |
this.value = 0 | |
end | |
end | |
}, | |
{ | |
name = "ETTR Set Time?", | |
help = "A camera specific variable in seconds", | |
help2 = "Change if ETTR fails to find a solution", | |
min = 2, | |
max = 8, | |
value = 4 | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment