AdaptiveMD[]
- Written for/on: S3IS
- Also works on: Needs adaptation of button presses for A-series
- Required CHDK build: Fingalo 124 and up, AllBest 16 and up
Documentation/Help (save as a small "AdaptiveMD.txt" file to your /CHDK/SCRIPTS/ folder)
This script uses the continuous mode of the camera to make a series of shots for a certain time (default 2.5 [s]) after motion is detected. The motion detection threshold is adapted to the circumstances, to avoid random detection or to avoid missing detection. Note that the adaptation algorithm is somewhat crude and needs to be tuned for the particular circumstances encountered. Tuning can be done by stepping through a grid of thresholds for motion detection for different light levels, and establishing a polynomial fit for light level versus nice threshold. Need integer coefficients for the fit.
The setting of the camera to continuous/fast shooting, spot metering, manual focus, and focus distance is done by the script. For this to work your camera's menus should be in start-up condition. You should select a program mode that allows manual focus, and only have to set the detection area, etc., and press the trigger For changing the period the script is active you have to edit this file, there are just not enough interface variables available.
Script Code (save as "AdaptiveMD.bas" to your /CHDK/SCRIPTS/ folder)
rem author: anonymous
rem camera: S3, CHDK Fingalo, build 124 or AllBest 16 and up
rem uses extended UBASIC, UC variables, timing, and motion detection
rem Save this file as "AdaptiveMD.bas" in the /CHDK/SCRIPTS directory
rem This script uses the continuous mode of the S3 to make a series of
rem shots for a certain time (default 2.5 [s]) after motion is detected.
rem The motion detection threshold is adapted to the circumstances,
rem to avoid random detection or to avoid missing detection.
rem Note that the adaptation algorithm is somewhat crude and needs to be
rem tuned for the particular circumstances encountered.
rem The setting of the camera to continuous/fast shooting, spot metering,
rem manual focus, and focus distance is done by the script.
rem For this to work your camera's menus should be in start-up condition.
rem You should select a program mode that allows manual focus,
rem and only have to set the detection area, etc., and press the trigger
rem For changing the period the script is active you have to edit this file,
rem there are just not enough interface variables available.
@title AdaptiveMD
rem Size of full grid is 16 by 12 (column x row).
rem Select (sub)area to be used for detection.
@param a Start column
@default a 10
@param b End column
@default b 16
@param c Start row
@default c 2
@param d End row
@default d 9
rem Set parameters for motion detection startup/sensitivity.
@param e Triggering Delay (.1s)
@default e 0
@param f Threshold (0-255)
@default f 24
rem f~=12 for sunny daylight, for dawn or dusk f~=36 is more reasonable.
@param g Pixel step (speed/accuracy)
@default g 8
@param h Compare Interval (ms)
@default h 100
@param i Measure mode (1-Y,0-U,2-V)
@default i 1
@param j Focal length (.1m)
@default j 68
rem basic sleeping interval [ms]
s=50
rem Checking/correcting a b c d e f g h i is already done in md.
e = e*100
j = j*100
rem Log the screen prints (the ``n'' parameter does not seem to work).
print_screen 1
print_screen 6
rem number of rectangles
N = (b-a+1)*(d-c+1)
print "Number of rectangles",N
rem Sets some props to get high speed shooting.
set_raw 0
rem Set continuous shooting.
get_prop 6 p
if p=1 then
print "Continuous mode found"
else
while p<>1
click "timer"
get_prop 6 p
wend
print "Mode set to continuous"
endif
rem Set high speed shooting.
get_prop 8 p
if p=0 then
print "Hi-speed mode found"
else
click "menu"
sleep 17*s
for n=1 to 4
click "down"
next n
click "right"
click "menu"
sleep 13*s
get_prop 8 p
if p=0 then
print "Mode set to Hi-speed"
else
print "Mode not set to Hi-speed"
endif
endif
rem Set metering mode to spot.
get_prop 9 p
if p=1 then
print "Spot metering found"
else
click "erase"
sleep 7*s
for n=1 to 5
click "down"
next n
while p<>1
click "right"
get_prop 9 p
wend
click "erase"
print "Metering mode set to spot"
endif
rem Set to manual focus (so we can use set_focus command).
get_prop 12 p
if p=1 then
print "Manual focus (MF) found"
else
while p<>1
click "mf"
get_prop 12 p
wend
print "Focus set to manual (MF)"
endif
rem Set properties for shots at main location.
if j>0 then
set_focus j
endif
get_focus p
print "Focus set to",p
sleep 5000
print "Set up camera position"
md_detect_motion 16,12,i,30000,h,255,1,n,1,a,c,b,d,0,g,e
print "----------------"
print "Starts at 9:00"
print "Runs until 16:00"
rem get_day_seconds does not seem to take account of daylight saving time.
t = get_day_seconds
s = get_tick_count
rem Make D time of day [ms] at start of camera.
rem Gives time error bound of approx 1s,
rem but delta time error bound only approx 10ms.
D = t*1000-s
T = (9*60+0)*60
print "Sleeping for " (T-t)
sleep (T-t)*1000
T = (16*60+0)*60
x = 60000
rem Uses adaptation of threshold to avoid unnecessary triggering or
rem to avoid the loss of opportunity for nice snaps due to dependency
rem of threshold on lighting conditions.
rem Works by setting threshold as function of tv after a shot and by
rem reducing the threshold after period of inactivity by integrating
rem control with a certain gain, to be tuned for a given application.
rem The integration control could be replaced by a shoot_half type
rem of approach to get tv coming, but this takes too much time.
rem Not completely satisfactory, but may do.
z = 1
X = 5
print "0Threshold = " f
rem /--/-columns, rows to split picture into
rem | | measure mode (Y,U,V R,G,B) - U-0, Y-1, V-2, 3-R, 4-G, 5-B
rem | | | timeout
rem | | | | comparison interval (msec)
rem | | | | | threshold ( difference in cell to trigger detection)
rem | | | | | | draw_grid (0-no, 1-yes)
rem | | | | | | | return variable, number of cells with motion detected
rem | | | | | | | | VVVVVV OPTIONAL PARAMETERS: VVVV
rem | | | | | | | | region (masking) mode: 0-no regions, 1-include, 2-exclude
rem | | | | | | | | | region first column
rem | | | | | | | | | | region first row
rem | | | | | | | | | | | region last column
rem | | | | | | | | | | | | region last row
rem | | | | | | | | | | | | | parameters- 1-make immediate shoot, 2-log debug information into file. OR-ed values are accepted
rem | | | | | | | | | | | | | | pixels step - speed vs. Accuracy adjustments (1-use every pixel, 2-use every second pixel, etc)
rem | | | | | | | | | | | | | | | number of milliseconds to wait before begin triggering - can be useful for calibration with "draw_grid" option
rem | | | | | | | | | | | | | | | |
rem V V V V V V V V V V V V V V V V
while t<T
n=0
md_detect_motion 16,12,i, x, h, f, 1, n, 1, a, c, b, d, 0, g, e
s = get_tick_count
if n>0 and n<(N/2+1) then
press "shoot_full"
rem If n large then quite likely the image has not been stabilized due to
rem conflict with preceeding actions (shooting/file storage) in camera.
rem Could increase Triggering Delay, but is shooting conditions dependent.
rem Wait for priming of first shot to finish to get camera_tv.
do
get_prop 205 p
until p=1
rem Get tv (get_tv function not used, has less resolution).
get_prop 69 P
p = P
if p>500 then
p = 500
endif
if p<200 then
p = 200
endif
rem Compute threshold based on lighting conditions (tv).
rem 2nd order polynomial valid for 200 < p < 500, needs tuning.
rem Uses first order filter to cancel glitches in tv determination.
f = (4*f+5*(64+p*(p-1500)/10000))/9
z = 1
t = (D+s)/1000
print "S"t/3600":"t%3600/60":"t%60"."(D+s)%1000/10,"tf",P,f,n
sleep 2500+s-get_tick_count
rem After release wait for shoot_full to finish.
release "shoot_full"
do
get_prop 205 p
until p<>1
endif
if n>(N/2) then
t = (D+s)/1000
print "N",t/3600":"t%3600/60":"t%60"."(D+s)%1000/10,"Nn",N,n
endif
if n=0 then
z = z+1
if z>X and f>11 then
f = (14*f)/15
t = (D+s)/1000
print "T ",t/3600":"t%3600/60":"t%60"."(D+s)%1000/10,"f",f
z = 1
endif
endif
wend
print "Too long at the job"
print "-------------------"
end
rem The multiple statement 'if then else endif' does not work
rem correctly when the 'else' part is present, so this is avoided.
rem With 'else' it also seems to have worse timing properties,
rem but this may be due to the incorrect implementation.