yet another DOF stacker[]
- Written for/on: Powershot A710
- Also works on: Should work on any VxWorks DIGIC II -cam without modifications, needs to be modified for at least DRYOS-cams. (uses property cases, see the script)
- Required CHDK build: Anything recent with get_exp_count and is_pressed
Script version 20080516.
Works with any review setting. If you don't use review (at all), see code line 137 (in loop_shoot).
This script tries to make DOF (with HDR) stacking easy & accurate for every aperture & zoom value. (Alas, greater zoom values don't quite work. If someone comes up with a more accurate, yet fast enough approach(es) for changing focus, please share your knowledge.)
Usage is pretty straightforward: dial to M/Av, set parameters, focus to one end of the desired DOF. Run the script and set the other end or use zoom_out/zoom_in to set min/max focus value. Manual focus mode has to be active (so that focus can be changed with left/right), use +/- to change if necessary. No need to estimate subject depths, guess needed steps to get gapless DOF...
The greater the value for a/b, the further the DOF will move. 3/5 should overlap the fields by 2/5 (=hopefully enough), 7/8 by 1/8 (=probably not enough), 1/2 by 1/2.
Script should now work accurately (enough) and fast on the whole focusing range. Also hyperfocal point can be checked (=no shots are taken beyond HYP).
Multiple exposures can be taken on each focus step. This can be used e.g. with CHDK's Tv bracketing to do a (un)limited-DOF-HDR-stack. :]
"max gaps in DOF" is what it says: it's the maximum number of allowed (potential) gaps in DOF before aborting script execution.
Script Code (save as "yaDOFs.bas" to your /SCRIPTS/ folder)
@title yet another DOF stacker @param a move DOF @default a 3 @param b by (a/b) @default b 5 @param e take n shots/step @default e 1 @param g delay 1st shot (sec) @default g 5 @param j HYP checking @default j 1 @param o max gaps in DOF @default o 0 rem different propcases for DIGIC II/III rem S(hooting in progress-propcase): rem for DIGIC II: 205, DIGIC III: 206 S=205 rem D(rive mode -property case) - II:6, III:102? rem C(ontinuous-value for drive mode) - II:1, III:? D=6 C=1 if a<1 then a=1 if b<1 then b=2 if e<1 then e=1 if g<1 then g=5 if (j<0 or j>1) then j=1 if o<0 then o=0 G=0 if e>1 then if (get_prop D)<>C then print "set drive mode" print "to continuous" goto "the_end" endif endif f=get_focus print "-set M/Av" print "-set focus" print "-set MF" print "-zoom_out for nearest" print "-zoom_in for inf" wait_click cls print "-menu continues" print "-set MF" print "-zoom_out for nearest" print "-zoom_in for inf" do if is_pressed "shoot_half" then gosub "press_release_shoot_half" if is_pressed "left" then gosub "press_release_left" if is_pressed "down" then gosub "press_release_down" if is_pressed "right" then gosub "press_release_right" if is_pressed "up" then gosub "press_release_up" if is_pressed "set" then gosub "press_release_set" if is_pressed "macro" then gosub "press_release_macro" if is_pressed "mf" then gosub "press_release_mf" if is_pressed "flash" then gosub "press_release_flash" if is_pressed "erase" then gosub "press_release_erase" if is_pressed "zoom_in" then goto "set_inf" if is_pressed "zoom_out" then goto "set_near" if is_pressed "menu" then goto "theotherside_set" until 1<0 :set_inf set_focus 65535 goto "theotherside_set" :set_near rem smallest focus value for A710 is actually 59, what about A6x0 and S3? set_focus 55 :theotherside_set cls for t=0 to g-1 print "waiting", (g-t) "sec" sleep 930 next t cls l=get_focus if f<l then goto "order_ok" t=f f=l l=t :order_ok set_focus f t=f :loop_shoot rem last shot @ defined focus if t>=l then goto "shoot_last" gosub "sub_shoot_count" rem no need for additional shots, if last was beyond HYP if (f>=h and j=1) then goto "beyond_hyp" rem new focus @ current_DOF*a/b m=d*a/b rem better move new focus at least a bit if m<1 then m=1 i=f t=(f+m) set_focus t f=get_focus if f=t then goto "loop_shoot" rem if you don't use review, you can (don't have to) rem the following line (used to cancel review) click "shoot_half" rem if focus didn't move at all/is wrong, move it with right&left :loop_inc if f>t then goto "loop_dec" if f=t then goto "loop_shoot" click "right" f=get_focus goto "loop_inc" :loop_dec if f<=t then goto "loop_shoot" u=get_focus click "left" f=get_focus rem if wasn't able to move focus if (f<=i and o=0) then goto "didnt_focus" if (f<=i and o>0) then if (G>=o or u<=i) then goto "didnt_focus" G=G+1 print "gap in DOF (" G " of max. " o ")" set_focus u goto "loop_shoot" endif goto "loop_dec" :didnt_focus print "ERROR:" if G>0 then print "possible gaps: " G "," print "couldn't shoot" print "gapless DOF" goto "the_end" :beyond_hyp if G>0 then print "possible gaps: " G "," else print "all OK:" print "last shot(s)" print "beyond HYP" goto "the_end" :shoot_last print "shoot_last" set_focus l gosub "sub_shoot_count" if G>0 then print "possible gaps: " G "," else print "all OK:" print "last shot(s)" print "@ defined location" :the_end end :sub_shoot_count C=get_exp_count press "shoot_half" press "shoot_full" do until (get_exp_count-C)>=e d=get_dof h=get_hyp_dist release "shoot_full" do until get_shooting=0 return :press_release_shoot_half press "shoot_half" while is_pressed "shoot_half" if is_pressed "down" then gosub "press_release_down" if is_pressed "mf" then gosub "press_release_mf" if is_pressed "macro" then gosub "press_release_macro" wend release "shoot_half" return :press_release_left press "left" do until is_pressed "left" = 0 release "left" return :press_release_right press "right" do until is_pressed "right" = 0 release "right" return :press_release_up press "up" do until is_pressed "up" = 0 release "up" return :press_release_down press "down" do until is_pressed "down" = 0 release "down" return :press_release_set press "set" do until is_pressed "set" = 0 release "set" return :press_release_erase press "erase" do until is_pressed "erase" = 0 release "erase" return :press_release_macro press "macro" do until is_pressed "macro" = 0 release "macro" return :press_release_mf press "mf" do until is_pressed "mf" = 0 release "mf" return :press_release_flash press "flash" do until is_pressed "flash" = 0 release "flash" return
Jucifer 17:12, 19 April 2008 (UTC)
yet another DOF stacker (old version)[]
- Written for/on: Powershot A710
- Also works on: Should work on A6x0 and S3 with minor modification, others may need major modifications.
Script version 20071231.
Works with any review setting. If you don't use review (at all), see code line 166 (in loop_shoot).
This script tries to make DOF stacking easy & accurate for every aperture & zoom value. (Alas, greater zoom values don't quite work. If someone comes up with a more accurate, yet fast enough approach(es) for changing focus, please share your knowledge.)
Usage is pretty straightforward: dial to M/Av, set parameters, use MF to focus to one end of the desired DOF (MF has to have focus, use +/- to change if necessary...). Run the script and set the other end or use zoom_out/zoom_in to set min/max focus value. No need to estimate subject depths, guess needed steps to get gapless DOF...
The greater the value for a/b, the further the DOF will move. 3/5 should overlap the fields by 2/5 (=hopefully enough), 7/8 by 1/8 (=probably not enough), 1/2 by 1/2.
Script should now work accurately (enough) and fast on the whole focusing range. Also hyperfocal point can be checked (=no shots are taken beyond HYP).
A6x0 users: if min aperture values are different for A6x0, please do add the needed table(s). (To see the values, turn on misc OSD items, (zoom 0?, )set short Tv (e.g. 1/2000), set Av, half-press shutter, read the actual Av. Then set next Av and read the value. Iterate.)
Thanks to Keo for the S3 Av table.
Feel free to contribute.
Script Code (save as "yaDOFs.bas" to your /SCRIPTS/ folder)
@title yet another DOF stacker @param a move DOF @default a 3 @param b by (a/b) @default b 5 @param c MF steps on up/down @default c 5 @param g delay 1st shot (sec) @default g 5 @param j HYP checking @default j 1 if a<1 then let a=1 if b<1 then let b=2 if c<1 then let c=5 if g<1 then let g=5 if j<0 then let j=1 if j>1 then let j=1 get_av v get_zoom z get_focus f rem since real Av can't be read by scripts(, right?), tables are based on min aperture values ...ish rem (to have the error on the safe side) if v=9 then let v=2870 if v=10 then let v=2950 if v=11 then let v=3220 if v=12 then let v=3910 if v=13 then let v=4310 if v=14 then let v=4800 if v=15 then let v=5350 if v=16 then let v=5900 if v=17 then let v=6440 if v=18 then let v=7820 rem Focal Length table, based on grand/platform/a710/main.c if z=0 then let z=5800 if z=1 then let z=6420 if z=2 then let z=7060 if z=3 then let z=7700 if z=4 then let z=8340 if z=5 then let z=9950 if z=6 then let z=11550 if z=7 then let z=13160 if z=8 then let z=14750 if z=9 then let z=17150 if z=10 then let z=19570 if z=11 then let z=22760 if z=12 then let z=26750 if z=13 then let z=30750 if z=14 then let z=34800 rem HYP calculation based on grand/core/gui_osd.c h=z*z/5/v print "-set M/Av and MF" print "-use down/left or" print " up/right to change focus" print "-zoom_out for nearest" print "-zoom_in for inf" wait_click cls print "-shoot_half continues" print "-zoom_out for nearest" print "-zoom_in for inf" is_key k "left" if k=1 then goto "focus_in" is_key k "down" if k=1 then goto "focus_in_more" is_key k "right" if k=1 then goto "focus_out" is_key k "up" if k=1 then goto "focus_out_more" is_key k "zoom_in" if k=1 then goto "set_inf" is_key k "zoom_out" if k=1 then goto "set_near" :loop_zoom wait_click is_key k "left" if k=1 then goto "focus_in" is_key k "down" if k=1 then goto "focus_in_more" is_key k "right" if k=1 then goto "focus_out" is_key k "up" if k=1 then goto "focus_out_more" is_key k "shoot_half" if k=1 then goto "theotherside_set" is_key k "zoom_in" if k=1 then goto "set_inf" is_key k "zoom_out" if k=1 then goto "set_near" goto "loop_zoom" :focus_in click "left" goto "loop_zoom" :focus_in_more for i=1 to c click "left" next i goto "loop_zoom" :focus_out click "right" goto "loop_zoom" :focus_out_more for i=1 to c click "right" next i goto "loop_zoom" :set_inf set_focus 65535 goto "theotherside_set" :set_near rem smallest focus value for A710 is actually 59, what about A6x0 and S3? set_focus 55 :theotherside_set cls for t=0 to g-1 print "waiting", (g-t) "sec" sleep 930 next t cls get_focus l if f<l then goto "order_ok" t=f f=l l=t :order_ok set_focus f t=f :loop_shoot rem last shot @ defined focus if t>=l then goto "shoot_last" shoot rem no need for additional shots, if last was beyond HYP if (f>=h and j=1) then goto "beyond_hyp" rem DOF=R2-R1 d=((h*f)/(h-f)-(h*f)/(h+f)) rem new focus @ current_DOF*a/b e=d*a/b rem better move new focus at least a bit if e<1 then e=1 i=f t=(f+e) set_focus t get_focus f if f=t then goto "loop_shoot" rem if you don't use review, you can (don't have to) rem the following line (used to cancel review) click "shoot_half" rem if focus didn't move at all/is wrong, move it with right&left :loop_inc if f>t then goto "loop_dec" if f=t then goto "loop_shoot" click "right" get_focus f goto "loop_inc" :loop_dec if f<=t then goto "loop_shoot" click "left" get_focus f rem if wasn't able to move focus any further, end if f<=i then goto "didnt_focus" goto "loop_dec" :shoot_last set_focus l shoot print "all OK:" print "last shot" print "@ defined location" goto "the_end" :beyond_hyp print "all OK:" print "last shot" print "beyond HYP" goto "the_end" :didnt_focus print "ERROR:" print "couldn't shoot" print "gapless DOF" :the_end end
Script should work on A6x0 with the focal length table replaced with:
if z=0 then let z=7300 if z=1 then let z=8460 if z=2 then let z=9565 if z=3 then let z=10835 if z=4 then let z=12565 if z=5 then let z=14926 if z=6 then let z=17342 if z=7 then let z=21709 if z=8 then let z=29200
...and S3's focal length table:
if z=0 then let z=6000 if z=1 then let z=6036 if z=2 then let z=6072 if z=3 then let z=6109 if z=4 then let z=6145 if z=5 then let z=6181 if z=6 then let z=6218 if z=7 then let z=6245 if z=8 then let z=6290 if z=9 then let z=6327 if z=10 then let z=6363 if z=11 then let z=6400 if z=12 then let z=6590 if z=13 then let z=6780 if z=14 then let z=6970 if z=15 then let z=7160 if z=16 then let z=7350 if z=17 then let z=7540 if z=18 then let z=7730 if z=19 then let z=7920 if z=20 then let z=8110 if z=21 then let z=8300 if z=22 then let z=8490 if z=23 then let z=8680 if z=24 then let z=8870 if z=25 then let z=9060 if z=26 then let z=9250 if z=27 then let z=9440 if z=28 then let z=9630 if z=29 then let z=9820 if z=30 then let z=10010 if z=31 then let z=10200 if z=32 then let z=10390 if z=33 then let z=10580 if z=34 then let z=10770 if z=35 then let z=10960 if z=36 then let z=11150 if z=37 then let z=11340 if z=38 then let z=11530 if z=39 then let z=11720 if z=40 then let z=11910 if z=41 then let z=12100 if z=42 then let z=12500 if z=43 then let z=12900 if z=44 then let z=13300 if z=45 then let z=13700 if z=46 then let z=14100 if z=47 then let z=14500 if z=48 then let z=14900 if z=49 then let z=15300 if z=50 then let z=15700 if z=51 then let z=16100 if z=52 then let z=16500 if z=53 then let z=16900 if z=54 then let z=17300 if z=55 then let z=17700 if z=56 then let z=18100 if z=57 then let z=18500 if z=58 then let z=18900 if z=59 then let z=19300 if z=60 then let z=19700 if z=61 then let z=20100 if z=62 then let z=20500 if z=63 then let z=20900 if z=64 then let z=21300 if z=65 then let z=22222 if z=66 then let z=23145 if z=67 then let z=24068 if z=68 then let z=24990 if z=69 then let z=25913 if z=70 then let z=26836 if z=71 then let z=27759 if z=72 then let z=28681 if z=73 then let z=29604 if z=74 then let z=30527 if z=75 then let z=31450 if z=76 then let z=32372 if z=77 then let z=33295 if z=78 then let z=34218 if z=79 then let z=35140 if z=80 then let z=36063 if z=81 then let z=36986 if z=82 then let z=37909 if z=83 then let z=38831 if z=84 then let z=39754 if z=85 then let z=40677 if z=86 then let z=41600 if z=87 then let z=42642 if z=88 then let z=43684 if z=89 then let z=44726 if z=90 then let z=45768 if z=91 then let z=46810 if z=92 then let z=47852 if z=93 then let z=48894 if z=94 then let z=49936 if z=95 then let z=50978 if z=96 then let z=52021 if z=97 then let z=53063 if z=98 then let z=54105 if z=99 then let z=55147 if z=100 then let z=56189 if z=101 then let z=57231 if z=102 then let z=58273 if z=103 then let z=59315 if z=104 then let z=60357 if z=105 then let z=61400 if z=106 then let z=61860 if z=107 then let z=62321 if z=108 then let z=62782 if z=109 then let z=63243 if z=110 then let z=63704 if z=111 then let z=64165 if z=112 then let z=64626 if z=113 then let z=65086 if z=114 then let z=65547 if z=115 then let z=66008 if z=116 then let z=66469 if z=117 then let z=66930 if z=118 then let z=67391 if z=119 then let z=67852 if z=120 then let z=68313 if z=121 then let z=68773 if z=122 then let z=69234 if z=123 then let z=69695 if z=124 then let z=70156 if z=125 then let z=70671 if z=126 then let z=71078 if z=127 then let z=71539 if z=128 then let z=72000
...and S3 Aperture Value table (thank you, Keo).
if v=9 then let v=2770 if v=10 then let v=2970 if v=11 then let v=3240 if v=12 then let v=3910 if v=13 then let v=4340 if v=14 then let v=4800 if v=15 then let v=5350 if v=16 then let v=5900 if v=17 then let v=6440 if v=18 then let v=7820
Script Code - with modifications for S3 in place (save as "yaDOFsS3.bas" to your /SCRIPTS/ folder) Feb 5 2008
For your cut and past convenience I have taken the code above and replaced the value tables with those provided by Keo for the S3. The resulting script below is modified for the S3-IS.
@title yet another DOF stacker with S3 Values added thanks Keo @param a move DOF @default a 3 @param b by (a/b) @default b 5 @param c MF steps on up/down @default c 5 @param g delay 1st shot (sec) @default g 5 @param j HYP checking @default j 1 if a<1 then let a=1 if b<1 then let b=2 if c<1 then let c=5 if g<1 then let g=5 if j<0 then let j=1 if j>1 then let j=1 get_av v get_zoom z get_focus f rem since real Av can't be read by scripts(, right?), tables are based on min aperture values ...ish rem (to have the error on the safe side) if v=9 then let v=2770 if v=10 then let v=2970 if v=11 then let v=3240 if v=12 then let v=3910 if v=13 then let v=4340 if v=14 then let v=4800 if v=15 then let v=5350 if v=16 then let v=5900 if v=17 then let v=6440 if v=18 then let v=7820 rem Focal Length table, based on grand/platform/a710/main.c if z=0 then let z=6000 if z=1 then let z=6036 if z=2 then let z=6072 if z=3 then let z=6109 if z=4 then let z=6145 if z=5 then let z=6181 if z=6 then let z=6218 if z=7 then let z=6245 if z=8 then let z=6290 if z=9 then let z=6327 if z=10 then let z=6363 if z=11 then let z=6400 if z=12 then let z=6590 if z=13 then let z=6780 if z=14 then let z=6970 if z=15 then let z=7160 if z=16 then let z=7350 if z=17 then let z=7540 if z=18 then let z=7730 if z=19 then let z=7920 if z=20 then let z=8110 if z=21 then let z=8300 if z=22 then let z=8490 if z=23 then let z=8680 if z=24 then let z=8870 if z=25 then let z=9060 if z=26 then let z=9250 if z=27 then let z=9440 if z=28 then let z=9630 if z=29 then let z=9820 if z=30 then let z=10010 if z=31 then let z=10200 if z=32 then let z=10390 if z=33 then let z=10580 if z=34 then let z=10770 if z=35 then let z=10960 if z=36 then let z=11150 if z=37 then let z=11340 if z=38 then let z=11530 if z=39 then let z=11720 if z=40 then let z=11910 if z=41 then let z=12100 if z=42 then let z=12500 if z=43 then let z=12900 if z=44 then let z=13300 if z=45 then let z=13700 if z=46 then let z=14100 if z=47 then let z=14500 if z=48 then let z=14900 if z=49 then let z=15300 if z=50 then let z=15700 if z=51 then let z=16100 if z=52 then let z=16500 if z=53 then let z=16900 if z=54 then let z=17300 if z=55 then let z=17700 if z=56 then let z=18100 if z=57 then let z=18500 if z=58 then let z=18900 if z=59 then let z=19300 if z=60 then let z=19700 if z=61 then let z=20100 if z=62 then let z=20500 if z=63 then let z=20900 if z=64 then let z=21300 if z=65 then let z=22222 if z=66 then let z=23145 if z=67 then let z=24068 if z=68 then let z=24990 if z=69 then let z=25913 if z=70 then let z=26836 if z=71 then let z=27759 if z=72 then let z=28681 if z=73 then let z=29604 if z=74 then let z=30527 if z=75 then let z=31450 if z=76 then let z=32372 if z=77 then let z=33295 if z=78 then let z=34218 if z=79 then let z=35140 if z=80 then let z=36063 if z=81 then let z=36986 if z=82 then let z=37909 if z=83 then let z=38831 if z=84 then let z=39754 if z=85 then let z=40677 if z=86 then let z=41600 if z=87 then let z=42642 if z=88 then let z=43684 if z=89 then let z=44726 if z=90 then let z=45768 if z=91 then let z=46810 if z=92 then let z=47852 if z=93 then let z=48894 if z=94 then let z=49936 if z=95 then let z=50978 if z=96 then let z=52021 if z=97 then let z=53063 if z=98 then let z=54105 if z=99 then let z=55147 if z=100 then let z=56189 if z=101 then let z=57231 if z=102 then let z=58273 if z=103 then let z=59315 if z=104 then let z=60357 if z=105 then let z=61400 if z=106 then let z=61860 if z=107 then let z=62321 if z=108 then let z=62782 if z=109 then let z=63243 if z=110 then let z=63704 if z=111 then let z=64165 if z=112 then let z=64626 if z=113 then let z=65086 if z=114 then let z=65547 if z=115 then let z=66008 if z=116 then let z=66469 if z=117 then let z=66930 if z=118 then let z=67391 if z=119 then let z=67852 if z=120 then let z=68313 if z=121 then let z=68773 if z=122 then let z=69234 if z=123 then let z=69695 if z=124 then let z=70156 if z=125 then let z=70671 if z=126 then let z=71078 if z=127 then let z=71539 if z=128 then let z=72000 rem HYP calculation based on grand/core/gui_osd.c h=z*z/5/v print "-set M/Av and MF" print "-use down/left or" print " up/right to change focus" print "-zoom_out for nearest" print "-zoom_in for inf" wait_click cls print "-shoot_half continues" print "-zoom_out for nearest" print "-zoom_in for inf" is_key k "left" if k=1 then goto "focus_in" is_key k "down" if k=1 then goto "focus_in_more" is_key k "right" if k=1 then goto "focus_out" is_key k "up" if k=1 then goto "focus_out_more" is_key k "zoom_in" if k=1 then goto "set_inf" is_key k "zoom_out" if k=1 then goto "set_near" :loop_zoom wait_click is_key k "left" if k=1 then goto "focus_in" is_key k "down" if k=1 then goto "focus_in_more" is_key k "right" if k=1 then goto "focus_out" is_key k "up" if k=1 then goto "focus_out_more" is_key k "shoot_half" if k=1 then goto "theotherside_set" is_key k "zoom_in" if k=1 then goto "set_inf" is_key k "zoom_out" if k=1 then goto "set_near" goto "loop_zoom" :focus_in click "left" goto "loop_zoom" :focus_in_more for i=1 to c click "left" next i goto "loop_zoom" :focus_out click "right" goto "loop_zoom" :focus_out_more for i=1 to c click "right" next i goto "loop_zoom" :set_inf set_focus 65535 goto "theotherside_set" :set_near rem smallest focus value for A710 is actually 59, what about A6x0 and S3? set_focus 55 :theotherside_set cls for t=0 to g-1 print "waiting", (g-t) "sec" sleep 930 next t cls get_focus l if f<l then goto "order_ok" t=f f=l l=t :order_ok set_focus f t=f :loop_shoot rem last shot @ defined focus if t>=l then goto "shoot_last" shoot rem no need for additional shots, if last was beyond HYP if (f>=h and j=1) then goto "beyond_hyp" rem DOF=R2-R1 d=((h*f)/(h-f)-(h*f)/(h+f)) rem new focus @ current_DOF*a/b e=d*a/b rem better move new focus at least a bit if e<1 then e=1 i=f t=(f+e) set_focus t get_focus f if f=t then goto "loop_shoot" rem if you don't use review, you can (don't have to) rem the following line (used to cancel review) click "shoot_half" rem if focus didn't move at all/is wrong, move it with right&left :loop_inc if f>t then goto "loop_dec" if f=t then goto "loop_shoot" click "right" get_focus f goto "loop_inc" :loop_dec if f<=t then goto "loop_shoot" click "left" get_focus f rem if wasn't able to move focus any further, end if f<=i then goto "didnt_focus" goto "loop_dec" :shoot_last set_focus l shoot print "all OK:" print "last shot" print "@ defined location" goto "the_end" :beyond_hyp print "all OK:" print "last shot" print "beyond HYP" goto "the_end" :didnt_focus print "ERROR:" print "couldn't shoot" print "gapless DOF" :the_end end
--Jucifer 17:52, 31 December 2007 (UTC)