- 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.