Accessing Motion Detection Actual Values? - Script Writing - CHDK Forum

Accessing Motion Detection Actual Values?

  • 32 Replies
  • 5128 Views
*

Offline Davo

  • ***
  • 174
Accessing Motion Detection Actual Values?
« on: 08 / February / 2013, 07:23:07 »
Advertisements
Hi,

I am slowly getting to grips with md_detect_motion() under lua. It seems to me that it works by calculating the average channel brightness in each cell. At the next measure_interval it then re-checks these values until one or more cells differs by the threshold value or it times out. It then returns with the number of cells that have breached the threshold.

I can then use md_get_cell_diff() to produce an array (table) of values which are all zero if there is no movement. If there is movement, I get an array of the difference in brightness in each cell.

What I would like to do is access the actual values in each cell rather than the changes. Is this possible with CDHK?

thanks
Dave

Re: Accessing Motion Detection Actual Values?
« Reply #1 on: 08 / February / 2013, 08:00:12 »
I am slowly getting to grips with md_detect_motion() under lua. It seems to me that it works by calculating the average channel brightness in each cell. At the next measure_interval it then re-checks these values until one or more cells differs by the threshold value or it times out. It then returns with the number of cells that have breached the threshold.
Correct.

Take a look at this forum thread  and this  wiki page if you haven't already.

Quote
I can then use md_get_cell_diff() to produce an array (table) of values which are all zero if there is no movement. If there is movement, I get an array of the difference in brightness in each cell.
Correct.  You might be interested in this script : http://chdk.setepontos.com/index.php?topic=9366.msg96305#msg96305

Quote
What I would like to do is access the actual values in each cell rather than the changes. Is this possible with CDHK?
No.  Although it would not be a difficult feature to add if there was a good reason you needed it.
Ported :   A1200    SD940   G10    Powershot N    G16

*

Offline Davo

  • ***
  • 174
Re: Accessing Motion Detection Actual Values?
« Reply #2 on: 08 / February / 2013, 09:53:20 »
Thanks for the detailed response. I have been following the md second look thread with interest. I have a Zigview for DSLRs that cost £200 and your updates have given the same and more features for free  :). Check out the online pdf manual to see what I mean.

I am trying to video record birds on my garden feeder. md_detect_motion() can detect when a bird lands OK to start the video. It can also keep recording while the bird is moving about. However, if the bird stops moving it will return an array of zeros which turns off the video early.

What would be perfect would be a function like

scene{} = get_scene(cols, rows, pixel_measure_mode, pixel_step)

which would return the array of average tile levels whenever it was called. I could then snap a reference scene and compare it with the current scene to see when the bird had left.

I don't know if get_scene() needs to be part of the md_detect_motion() call. If it was separate it would maybe give scripters more flexibility in writing their own routines.

Dave

Re: Accessing Motion Detection Actual Values?
« Reply #3 on: 08 / February / 2013, 11:42:05 »
What would be perfect would be a function like

     scene{} = get_scene(cols, rows, pixel_measure_mode, pixel_step)

which would return the array of average tile levels whenever it was called. I could then snap a reference scene and compare it with the current scene to see when the bird had left.
Interesting idea - not sure how well it would work with a real dynamic outdoor scene but it would be interesting to experiment with.  I would probably implement it as md_get_cell_abs()  (it will look like md_get_cell_diff() ).

I can prototype this pretty quickly and send you a custom build to see how well this works if you are willing to test it?  To do so,  I'll need to know your camera model and firmware version.
« Last Edit: 08 / February / 2013, 11:45:19 by waterwingz »
Ported :   A1200    SD940   G10    Powershot N    G16


*

Offline Davo

  • ***
  • 174
Re: Accessing Motion Detection Actual Values?
« Reply #4 on: 08 / February / 2013, 14:22:09 »
Brilliant!

I have an A810 running 1.0.0e.

Dave

Re: Accessing Motion Detection Actual Values?
« Reply #5 on: 08 / February / 2013, 17:55:16 »
I have an A810 running 1.0.0e.
Try this?  md_get_cell_abs() added for both Lua and uBASIC.   

CHDK file for your camera attached, along with patch file of what I did.

Here's a little Lua script that exercises the function :

Code: [Select]
--[[
@title Motion Tester
@param f Trigger Threshold
@default f 900
@param a Columns
@default a 2
@param b Rows
@default b 2
@param d Timeout
@default d 200
@param e Interval
@default e 100
]]
p=20        -- Trigger Delay (mSec)
c=1         -- measure mode (Y,U,V R,G,B) U=0, Y=1, V=2, R=3, G=4, B=5
g=3         -- draw grid (0=no, 1=yes)   
h=0         -- not used in LUA
i=0         -- region masking mode: 0=no regions, 1=include, 2=exclude
j=0         --      first column
k=0         --      first row
l=0         --      last column
m=0         --      last row
n=0         -- optional parameters  (1=shoot immediate)
o=1         -- pixel step

screenwidth=360
screenheight=240
colsize=screenwidth/a
rowsize=screenheight/b

if ( get_mode() == false ) then
    set_record(1)
    while ( get_mode() == false ) do
        sleep(100)
    end
end
sleep(2000)
repeat
    zones = md_detect_motion( a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p)
    for row=1,b do
      for col=1,a do
           x = md_get_cell_abs(col,row)
           draw_string( (col-1)*colsize+colsize/4, (row-1)*rowsize+rowsize/4, " "..math.abs(x).."   ", 258, 263)
       end
    end
until (false)
Ported :   A1200    SD940   G10    Powershot N    G16

*

Offline Davo

  • ***
  • 174
Re: Accessing Motion Detection Actual Values?
« Reply #6 on: 09 / February / 2013, 07:30:29 »
Thanks for a fantastic job! I just tried it on my camera and it looks like exactly what I was looking for. I can also see why it made more sense to make it part of the md code.

I am now working up a "reverted to initial scene?" test script to try it out which I will post here.

Thanks again, Dave

ps Your zip was missing the PS.FI2 file but I just used the one from the latest autobuild.

*

Offline Davo

  • ***
  • 174
Re: Accessing Motion Detection Actual Values?
« Reply #7 on: 09 / February / 2013, 08:43:20 »
This is looking really good. I modified your code below so I could run some tests. What it does is run a loop that first records the actual cell levels for the original scene. It then does a standard wait for motion to happen. Once motion is detected, it checks the current cell levels until they are the same as the original scene.  This test doesn't trigger the camera but only displays a message.

Function fill_md_array(name) records the scene levels and function compare_scenes(original, current, sensitivity) does the scene comparison. The sensitivity value allows for the fact that the levels will probably never match exactly.

This works fine on my desk - now for a real life test.

Dave

Code: [Select]
--[[
@title Motion Tester
@param a Columns
@default a 3
@param b Rows
@default b 2
@param f Trigger Threshold
@default f 10
@param d Time out (s)
@default d 20
@param s Sensitivity
@default s 5
]]
c=1         -- measure mode (Y,U,V R,G,B) U=0, Y=1, V=2, R=3, G=4, B=5
g=3         -- draw grid (0=no, 1=yes)   
h=0         -- not used in LUA
i=0         -- region masking mode: 0=no regions, 1=include, 2=exclude
j=0         --      first column
k=0         --      first row
l=0         --      last column
m=0         --      last row
n=0         -- optional parameters  (1=shoot immediate)
o=1         -- pixel step
p=0        -- Trigger Delay (mSec)

function fill_md_array(name)
  for row = 1, b do
    for col = 1, a do
      name[(row - 1) * a + col] = md_get_cell_abs(col,row)
    end -- for col
  end -- for row
end -- fill_array()

function compare_scenes(original, current, sensitivity)
  for row = 1, b do
    for col = 1, a do
      if math.abs(original[(row - 1) * a + col] - current[(row - 1) * a + col]) > sensitivity then
        return false
      end -- if
    end -- for col
  end -- for row
  return true
end -- compare_scenes()

if ( get_mode() == false ) then
    set_record(1)
    while ( get_mode() == false ) do
        sleep(100)
    end
end
sleep(2000)

md_original = {}
md_current = {}

repeat
  zones = md_detect_motion( a, b, c, 200, 100, f, g, h, i, j, k, l, m, n, o, p)
  fill_md_array(md_original)
  print("Original snapped.")
  zones = md_detect_motion( a, b, c, d*1000, 100, f, g, h, i, j, k, l, m, n, o, p)
  if zones > 0 then
    print("Event started.")
    repeat
      zones = md_detect_motion( a, b, c, 200, 100, f, g, h, i, j, k, l, m, n, o, p)
      fill_md_array(md_current)   
    until compare_scenes(md_original, md_current, s) == true
    print("Event over.")
  else
    print("Timed out.")
  end
until false


Re: Accessing Motion Detection Actual Values?
« Reply #8 on: 09 / February / 2013, 09:47:05 »
ps Your zip was missing the PS.FI2 file but I just used the one from the latest autobuild.
That normally will not work - the ps.fi2 file is CHDK if you are using the firmware updated method to load CHDK  Its not needed if you use the sd card lock autobooting method  - CHDK is in the diskboot.bin file .  So if you got the one off the autobuild and you are not autobooting then you are not loading the right file.   There is an outside chance it would work anyway as most of the changes are to the loadable modules and you are using the ones I gave you.  Which way are you loading CHDK?  And if you are using the firmware update method you really should try autobooting instead - its a lot more convenient.  http://chdk.wikia.com/wiki/Prepare_your_SD_card

This is looking really good. I modified your code below so I could run some tests. What it does is run a loop that first records the actual cell levels for the original scene. It then does a standard wait for motion to happen. Once motion is detected, it checks the current cell levels until they are the same as the original scene.  This test doesn't trigger the camera but only displays a message.

Function fill_md_array(name) records the scene levels and function compare_scenes(original, current, sensitivity) does the scene comparison. The sensitivity value allows for the fact that the levels will probably never match exactly.
There might be some better ways to implement this - philmoz and I had a discussion in IRC about it last night.   I thought I'd wait and see if you can get something working first though.


Ported :   A1200    SD940   G10    Powershot N    G16

*

Offline Davo

  • ***
  • 174
Re: Accessing Motion Detection Actual Values?
« Reply #9 on: 09 / February / 2013, 11:53:55 »
I tried to make a bootable card with your zipped package. However, the update firmware option would not show in the Canon menu so I couldn't start chdk to make the card bootable.

I then tried the latest autobuild and it worked fine. Inspection showed that it also had the PS file so I borrowed it for your package. This let me create a bootable card from your package and try out your script. I assumed that the PS file enabled the update firmware menu item but I was obviously wrong. I have now deleted the PS file and chdk and the test script are still working.

I will incorporate your new call in my birdcam script and give it a good tryout tomorrow. Is there any specific testing you want me to try?

Dave

 

Related Topics