CHDK Wiki
Register
Advertisement

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.

--131.155.54.3

Advertisement