Motion detection with variable AF frame position - Script Writing - CHDK Forum

Motion detection with variable AF frame position

  • 11 Replies
  • 4322 Views
Motion detection with variable AF frame position
« on: 25 / January / 2009, 17:57:57 »
Advertisements
Just wondering if anyone has already tried this before I spend time on it.  This is for an S3 IS, which allows you to adjust the position of the AF frame before autofocusing.  I don't know how many other models can do that.

I'm thinking that after the md_detect_motion call, I could call md_get_cell_diff for each cell (in a nested For loop).  Every time it finds a cell where there has been a difference higher than the threshold, it would move the AF frame to that cell's position then autofocus and shoot.

The display would have to be divided into about a 5x5 grid, with the outer ones being ignored because the AF frame can't be moved there.

This is for situations where the potential subjects may be at varying distances, say a flock of birds feeding on the ground and the camera is only 3m away at a hight of 0.5m.

I'm also wondering about avoiding false triggering by foliage moving in the wind.  Perhaps just using the R measuring mode would make it less sensitive to moving green objects.  Any thoughts?

Re: Motion detection with variable AF frame position
« Reply #1 on: 31 / January / 2009, 01:11:56 »
OK, no replies, so I guess no one's tried it before.  Here's my script, based on the general purpose MD script at:
http://chdk.wikia.com/wiki/UBASIC/Scripts:_Multipurpose_Motion_Detection

Only tested on an S3, camera needs to be in any mode but Auto so that it can move the AF frame.  Initial tests show it can work, but not reliably.

The idea is that after motion is detected, it loops to check each cell.  For each cell where a difference was recorded, it moves the AF frame over that cell and executes the "shot" command.

Unfortunately there's no quick way to move the AF frame.  On the S3 you have to click Set, then move it with cursor clicks.  Rather than try to keep track of the current frame position, I return it to the centre each time.  This is done by pressing Set for about a second.

I'm executing:
   print "C"
   press "set"
   sleep 2000
   release "set"
   click "set"
   print "C done"

1000ms should be more than enough, but sometimes I see the diagnostic "C" and "C done" come up almost immediately.  Is that Sleep command reliable?  What happens then is that it isn't in AF frame moving mode when it should be, and the remaining photos get taken with the AF frame in the centre.  Sometimes it works great.

As for the usefulness of the script, I haven't tried it on any real world subjects yet.  It could take quite a few seconds for it to work its way through all the photos it needs to take for each detection, and anything but a slow moving subject could be either long gone or moved to another frame.

Re: Motion detection with variable AF frame position
« Reply #2 on: 31 / January / 2009, 01:12:54 »
And here's the script I forgot to add to the previous posting:

rem Based on original script by  MLuna - based om MX3 sample script
rem 29 Jan 2009 pshute
rem Added value of 4 to param "a" (Shot). When set to 4, camera will detect movement
rem using all but the outer cells of a 5x5 grid.  When motion is detected, a shot with
rem AF is taken for each cell where a change was recorded, after first moving the AF frame
rem over that cell.
rem Tested on S3IS only
rem Use with caution!
rem vars used: a-k, l-n, t, H-J, T-V, X

@title Motion Detection with variable AF frame

rem Shot without auto-focus/with auto-focus/continuously (need to put in continuous mode manually)
rem T implies test mode with MD cells drawing and no shots taken
@param a Shot (0=nf/1=f/2=c/3=t/4=af))
@default a 1

rem How long the shutter button will be pressed in continuous mode
@param b Continuos shoot (secs)
@default b 10

@param c Threshold (0-255)
@default c 5

@param d Compare Interval (msecs)
@default d 20

@param e Compare Interval (secs)
@default e 0

rem If this value is too small, the camera goes continuously shooting after the 1st shot.
rem Experiment with this value to find one fitted to your needs
@param f Begin Delay (secs)
@default f 5

@param g Pix step(speed/accuracy adj)
@default g 5

@param h Columns
@default h 6

@param i Rows
@default i 6

rem Frame width in which no MD is performed (in cell units)
@param j Dead frame
@default j 0

if a<0 then let a=0
if a>4 then let a=4
if c<0 then let c=0
if d<0 then let d-0
if e<0 then let e=0
if g<1 then let g=1
if h<1 then let h=1
if i<1 then let i=1
if j<0 then let j=0

rem If varAF mode set 5 rows and cols with 1 dead zone
if a<>4 then goto "notVarAF"
   h=5
   i=5
   j=1
:notVarAF

rem Conversions secs to msecs
let b=b*1000
let e=e*1000
let f=f*1000

let d=d+e

rem This is the timeout in msecs. After this period, the motion trap is rearmed.
let T=600000

rem Parameters for the Dead Frame
let J=j+1
let H=h-j
let I=i-j

let t=0
let k=0

print "press Shutter Button to Stop"

:repete

   if a=0 then press "shoot_half"
   md_detect_motion h, i, 1, T, d, c, 1, t, 1, J, J, H, I, 0, g, f
   print t,"cells triggered"
   if a=0 and t>0 then click "shoot_full"
   if a=1 and t>0 then shoot
   if a=2 and t>0 then goto "continuos"
   if a=3 then goto "test"
   if a=4 and t>0 then gosub "varAF"

   let t=0

goto "repete"

:varAF
   for n=2 to 4
      for m=2 to 4
         md_get_cell_diff m,n,p
         print m,n,p,c
         if (p*p)<(c*c) then goto "noVarAFshoot"
            gosub "AFframeCentre"
            if m=2 then gosub "AFframeLeft"
            if m=4 then gosub "AFframeRight"
            if n=2 then gosub "AFframeUp"
            if n=4 then gosub "AFframeDown"
            shoot
:noVarAFshoot         
      next m
   next n
   return

:continuos
   let X=get_tick_count
   press "shoot_full"

   :contloop
      let U=get_tick_count
      let V=(U-X)
   if V<b then goto "contloop"

   release "shoot_full"
goto "repete"

:test
   if t>0 then let k=k+1
   if t>0 then print k," Detected cells: ",t else print "No detection in 10 min!"
   let t=0
goto "repete"

:AFframeCentre
   print "C"
   press "set"
   sleep 1000
   release "set"
   click "set"
   print "C done"
   return
:AFframeUp
   print "U"
   click "set"
   for l=1 to 6
      click "up"
   next l
   click "set"
   return
:AFframeDown
   print "D"
   click "set"
   for l=1 to 6
      click "down"
   next l
   click "set"
   return
:AFframeLeft
   print "L"
   click "set"
   for l=1 to 10
      click "left"
   next l
   click "set"
   return
:AFframeRight
   print "R"
   click "set"
   for l=1 to 10
      click "right"
   next l
   click "set"
   return

end

Re: Motion detection with variable AF frame position
« Reply #3 on: 31 / January / 2009, 03:04:45 »
1000ms should be more than enough, but sometimes I see the diagnostic "C" and "C done" come up almost immediately.  Is that Sleep command reliable?  What happens then is that it isn't in AF frame moving mode when it should be, and the remaining photos get taken with the AF frame in the centre.  Sometimes it works great.
I've worked out the problem, it needed a Sleep after the Shot command. Working reliably now, but it could really do with some optimisation of the AF frame movements.  The Sleeps after Shot command and in the AF frame recentring gosub need some experimentation to see how much they can be reduced too.

It would be great if there was a property I could set for the AF frame location instead of manually moving it, as that would greatly increase the speed and reduce the complexity of the script.

I'd be interested to hear what results people get if they try the script.

Here's the corrected script:
rem Based on original script by  MLuna - based om MX3 sample script
rem 29 Jan 2009 pshute
rem Added value of 4 to param "a" (Shot). When set to 4, camera will detect movement
rem using all but the outer cells of a 5x5 grid.  When motion is detected, a shot with
rem AF is taken for each cell where a change was recorded, after first moving the AF frame
rem over that cell.
rem Tested on S3IS only
rem Use with caution!
rem vars used: a-k, l-n, t, H-J, T-V, X

@title Motion Detection with variable AF frame

rem Shot without auto-focus/with auto-focus/continuously (need to put in continuous mode manually)
rem T implies test mode with MD cells drawing and no shots taken
@param a Shot (0=nf/1=f/2=c/3=t/4=af))
@default a 1

rem How long the shutter button will be pressed in continuous mode
@param b Continuos shoot (secs)
@default b 10

@param c Threshold (0-255)
@default c 5

@param d Compare Interval (msecs)
@default d 20

@param e Compare Interval (secs)
@default e 0

rem If this value is too small, the camera goes continuously shooting after the 1st shot.
rem Experiment with this value to find one fitted to your needs
@param f Begin Delay (secs)
@default f 5

@param g Pix step(speed/accuracy adj)
@default g 5

@param h Columns
@default h 6

@param i Rows
@default i 6

rem Frame width in which no MD is performed (in cell units)
@param j Dead frame
@default j 0

if a<0 then let a=0
if a>4 then let a=4
if c<0 then let c=0
if d<0 then let d-0
if e<0 then let e=0
if g<1 then let g=1
if h<1 then let h=1
if i<1 then let i=1
if j<0 then let j=0

rem If varAF mode set 5 rows and cols with 1 dead zone
if a<>4 then goto "notVarAF"
   h=5
   i=5
   j=1
:notVarAF

rem Conversions secs to msecs
let b=b*1000
let e=e*1000
let f=f*1000

let d=d+e

rem This is the timeout in msecs. After this period, the motion trap is rearmed.
let T=600000

rem Parameters for the Dead Frame
let J=j+1
let H=h-j
let I=i-j

let t=0
let k=0

print "press Shutter Button to Stop"

:repete

   if a=0 then press "shoot_half"
   md_detect_motion h, i, 1, T, d, c, 1, t, 1, J, J, H, I, 0, g, f
   print t,"cells triggered"
   if a=0 and t>0 then click "shoot_full"
   if a=1 and t>0 then shoot
   if a=2 and t>0 then goto "continuos"
   if a=3 then goto "test"
   if a=4 and t>0 then gosub "varAF"

   let t=0

goto "repete"

:varAF
   for n=2 to 4
      for m=2 to 4
         md_get_cell_diff m,n,p
         print m,n,p,c
         if (p*p)<(c*c) then goto "noVarAFshoot"
            gosub "AFframeCentre"
            if m=2 then gosub "AFframeLeft"
            if m=4 then gosub "AFframeRight"
            if n=2 then gosub "AFframeUp"
            if n=4 then gosub "AFframeDown"
            shoot
            sleep 1000
:noVarAFshoot         
      next m
   next n
   return

:continuos
   let X=get_tick_count
   press "shoot_full"

   :contloop
      let U=get_tick_count
      let V=(U-X)
   if V<b then goto "contloop"

   release "shoot_full"
goto "repete"

:test
   if t>0 then let k=k+1
   if t>0 then print k," Detected cells: ",t else print "No detection in 10 min!"
   let t=0
goto "repete"

:AFframeCentre
   print "C"
   press "set"
   sleep 1000
   release "set"
   click "set"
   print "C done"
   return
:AFframeUp
   print "U"
   click "set"
   for l=1 to 6
      click "up"
   next l
   click "set"
   return
:AFframeDown
   print "D"
   click "set"
   for l=1 to 6
      click "down"
   next l
   click "set"
   return
:AFframeLeft
   print "L"
   click "set"
   for l=1 to 10
      click "left"
   next l
   click "set"
   return
:AFframeRight
   print "R"
   click "set"
   for l=1 to 10
      click "right"
   next l
   click "set"
   return

end


*

Offline fudgey

  • *****
  • 1705
  • a570is
Re: Motion detection with variable AF frame position
« Reply #4 on: 31 / January / 2009, 04:13:13 »
Your after-shoot delay should be minimized with a shoot state check loop. Take a look at the more recent MDFB script here: http://chdk.setepontos.com/index.php/topic,471.msg21328.html#msg21328.

As for AF frame position, I have no idea since my cam doesn't support moving it. But there may be a way. See http://chdk.wikia.com/wiki/PropertyCase. Digic II property 192 appears to be tied to AF frame position. Try reading it and writing to it (get_prop and set_prop) to find out if it can be used to move the box around. CHDK debug menu has a propcase viewer you can use to quickly find out how the propcase value changes when you move the AF frame.

If writing to prop 192 doesn't work, it's still possible that it can be done by finding something in the firmware that can do this and modifying CHDK to make use of that. This requires working with the disassembly.

Re: Motion detection with variable AF frame position
« Reply #5 on: 01 / February / 2009, 23:54:44 »
As for AF frame position, I have no idea since my cam doesn't support moving it. But there may be a way. See http://chdk.wikia.com/wiki/PropertyCase. Digic II property 192 appears to be tied to AF frame position. Try reading it and writing to it (get_prop and set_prop) to find out if it can be used to move the box around. CHDK debug menu has a propcase viewer you can use to quickly find out how the propcase value changes when you move the AF frame.
Thanks for that information, I didn't realise there was a later version of the script.  I can't work out this propcase viewer though.  I have found the debug menu but can't work out how to view the values.  Do I use the CmpProp ALT +/- action?  If so, where's the +/- button on an S3?

*

Offline fe50

  • ******
  • 3117
  • IXUS50 & 860, SX10 Star WARs-Star RAWs
    • fe50
Re: Motion detection with variable AF frame position
« Reply #6 on: 02 / February / 2009, 02:44:58 »
...I can't work out this propcase viewer though.  I have found the debug menu but can't work out how to view the values.  Do I use the CmpProp ALT +/- action?  If so, where's the +/- button on an S3?

Hi pshute,
see Debug Parameters:

-> Set Debug data display to [Props]
-> Set PropCase/ParamsData page to the page number you want
    (each page shows 10 values, e.g. '1' shows values 0 to 9, '3' shows value 30 to 39)
-> if you set ALT +/- debug action to [Page], you can "scroll" trough the pages without
    going into the menu each time; try the DISP key on your S3, maybe it's another key, test it out...
    (the [+/-] key is the key with the Canon Exposure setting menu)
-> when you found the key on the S3 you can change the paging direction with a "double click" to
     this key, see +/- debug action

Pls. report which key the S3 use, so we can update the documentation...

*

Offline fudgey

  • *****
  • 1705
  • a570is
Re: Motion detection with variable AF frame position
« Reply #7 on: 02 / February / 2009, 14:28:24 »
MDFB is not a version of the script in the wiki.

Pls. report which key the S3 use, so we can update the documentation...

I think it's the FUNC key.... they are both called "erase" in scripts (that's what it does in play mode for A series, I suppose for S series too then).


Re: Motion detection with variable AF frame position
« Reply #8 on: 02 / February / 2009, 18:14:22 »
I think it's the FUNC key.... they are both called "erase" in scripts (that's what it does in play mode for A series, I suppose for S series too then).
Yes, that's correct.  Not sure how I missed that, perhaps I didn't press it hard enough when I tried it and assumed it was the wrong button.  It also serves as the Erase button on the S3 in play mode, so that terminology is ok

Property 192 is listed as the x position of the AF frame, and that seems to be correct, except that I suspect that only some bytes of it apply.  With the frame in the centre, it's 1.  If I move it 1 step right, it's 1048577, which is 100001 hex. 2 steps is 200001 hex, 10 steps is A00001.

I'm guessing each property is 4 bytes?  In this case I'd say only the first 2 are actually the x position, and the other 2 are for something else.  Are there other properties like that?  If so, what's the recommended way of access just the necessary bytes?

I haven't tried changing it yet, but even if I can't, being able to read it will be very useful.  Now I'm trying to find the y position, and I'm trying to use the CmpProp ALT +/- action to get it to show me the changes.  But it doesn't seem to work, even when I change the x position.  It only ever shows a change at property 100, and a random one at that.  Should this feature work?

*

Offline fudgey

  • *****
  • 1705
  • a570is
Re: Motion detection with variable AF frame position
« Reply #9 on: 03 / February / 2009, 01:56:13 »
Property 192 is listed as the x position of the AF frame, and that seems to be correct, except that I suspect that only some bytes of it apply.  With the frame in the centre, it's 1.  If I move it 1 step right, it's 1048577, which is 100001 hex. 2 steps is 200001 hex, 10 steps is A00001.

I'm guessing each property is 4 bytes?  In this case I'd say only the first 2 are actually the x position, and the other 2 are for something else.  Are there other properties like that?  If so, what's the recommended way of access just the necessary bytes?

They can be several words, CHDK's standard way of handling them just treats them as ints or shorts. See ewavr's work on storing camera white balance to DNG for an example of treating longer properties in C: http://chdk.setepontos.com/index.php/topic,156.msg26212.html#msg26212.

But if you can get all necessary info from get_prop(), Lua can do bit operations (see wiki) including shifts.

I haven't tried changing it yet, but even if I can't, being able to read it will be very useful.  Now I'm trying to find the y position, and I'm trying to use the CmpProp ALT +/- action to get it to show me the changes.  But it doesn't seem to work, even when I change the x position.  It only ever shows a change at property 100, and a random one at that.  Should this feature work?

I think I tried it once or twice and it did work as instructed.

 

Related Topics