#!/usr/bin/env ruby # # Script to implement motion-detection against the Hawking HNC230G webcam # # Copyright Tim Haynes 2006- # Distributable under the terms of the Gnu Public Licence (GPL) - see # . # # # Usage: # ./cam-motion-detect.rb delay number rate # # where delay is how long to sleep between image-polls (1s), # number is the number of frames to shoot after motion is detected, # rate is the delay between frames captured after motion is detected. # # # It will create files named after the current date/time in the current # directory. # # Change the reference to `cam' below to use the hostname/IP# of your # camera. # delay=ARGV[0] || "1" delay=delay.to_f emergnumber=ARGV[1] || "10" emergnumber=emergnumber.to_i emergdelay=ARGV[2] || "0.2" emergdelay=delay.to_f require 'socket' require 'RMagick' include Magick xsize,ysize=640,480 def grabPic # grab a picture from the camera. Will retry disconn+reconnect in case of # failure. stop=0 while stop==0 stop=1 s=TCPSocket.new('cam', 4321) or die "Error connecting to camera" puts "Requesting data" s.write("0110\n") len=s.read(2).reverse.unpack("v")[0] 2.times {s.getc } puts "Len: #{len}" jpeg=s.read(len) puts "Getting image" begin img=Magick::Image.from_blob(jpeg)[0]; GC.start rescue puts "Oops, something went wrong there" stop=0 end s.close end img end def process(img) # massage an image to be suitable for comparison # here we compute the luminosity channel since rmagick's builtin doesn't work # and scale it down to half/quarter-size to remove tiny transient errors. img.colorize(0.25, 0.6, 0.15, 1, Magick::Pixel::from_color("grey")).modulate(1.25,0.01,1).scale(0.5) end def difference(a,b) # see "mean difference per pixel" in the RMagick docs a.difference(b)[1] end def grabLots(n,i) #number, interval # grab lots of images, invoked after motion is detected basedate=Time.now().to_s.gsub(" ", "_") n.to_i.times {|m| img=grabPic GC.start img.write("#{basedate}-#{m}.jpg") sleep i } end puts "Requesting pictures, every #{delay}s, each #{xsize}*#{ysize}" a=grabPic asmall=process(a) while(1==1) b=grabPic puts "calculating..." bsmall=process(b) #uncomment to debug # puts "Saving..." # # asmall.write("a.jpg") # bsmall.write("b.jpg") GC.start puts "Acquired image-pair" nme=difference(asmall,bsmall) puts "Difference: #{nme}" if nme>0.0002 then puts "ALARM!" grabLots(emergnumber, emergdelay) end sleep delay a=b asmall=bsmall end