Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python
- # Simple motion-detection using the picamera library.
- # Runs at up to 10 fps depending on resolution, etc.
- # This is demonstration / proof-of-concept code.
- # It probably isn't useful in a real application.
- # Nov. 30 2013 J.Beale
- from __future__ import print_function
- import io, os, time, datetime, picamera, cv2
- import numpy as np
- #width = 32
- #height = 16 # minimum size that works ?
- width =144
- height = 96
- frames = 0
- first_frame = True
- frac = 0.05 # fraction to update long-term average on each pass
- a_thresh = 16.0 # amplitude change detection threshold for any pixel
- pc_thresh = 20 # number of pixels required to exceed threshold
- avgmax = 3 # long-term average of maximum-pixel-change-value
- tfactor = 2 # threshold above max.average diff per frame for motion detect
- picHoldoff = 1.0 # minimum interval (seconds) between saving images
- fupdate = 10000 # report debug data every this many frames
- #fupdate = 10 # report debug data every this many frames
- logfile = "/home/pi/pics/cam-log.csv"
- np.set_printoptions(precision=2)
- f = open(logfile, 'a')
- f.write ("# cam log v0.1 Nov.28 2013 JPB\n")
- outbuf = "# Start: " + str(datetime.datetime.now()) + "\n"
- f.write (outbuf)
- f.flush()
- daytime = datetime.datetime.now().strftime("%y%m%d-%H_%M_%S.%f")
- daytime = daytime[:-3] # remove last three digits (xxx microseconds)
- print ("# Start at %s" % str(datetime.datetime.now()))
- stream = io.BytesIO()
- with picamera.PiCamera() as camera:
- camera.resolution = (width, height)
- camera.start_preview()
- time.sleep(2)
- start = time.time()
- while True:
- camera.capture(stream, format='jpeg', use_video_port=True)
- # time.sleep(0.15) # sometimes delay needed to avoid crashes (!?)
- stream.seek(0)
- data = np.fromstring(stream.getvalue(), dtype=np.uint8)
- image = cv2.imdecode(data, 1)
- image = image.astype(np.float32)
- (h,w,cols) = image.shape
- (xc,yc) = (h/2,w/2)
- frames = frames + 1
- if (frames % fupdate) == 0:
- print ("%s, %03d max = %5.3f, avg = %5.3f" % (str(datetime.datetime.now()),frames,max,avgmax))
- # print (avgcol); print (avgdiff)
- # print "%02d center: %s (BGR)" % (frames,image[xc,yc])
- if first_frame == False:
- newcol = image[:,:,1] # full image, green only
- avgcol = (avgcol * (1.0-frac)) + (newcol * frac)
- diff = newcol - avgcol # matrix of difference-from-average pixel values
- diff = abs(diff) # take absolute value of difference
- avgdiff = ((1 - frac)*avgdiff) + (frac * diff) # long-term average difference
- a_thresh = tfactor*avgmax # adaptive amplitude-of-change threshold
- condition = diff > a_thresh
- changedPixels = np.extract(condition,diff)
- countPixels = changedPixels.size
- max = np.amax(diff) # find the biggest (single-pixel) change
- avgmax = ((1 - frac)*avgmax) + (max * frac)
- if countPixels > pc_thresh: # notable change of enough pixels => motion!
- now = time.time()
- interval = now - start
- start = now
- daytime = datetime.datetime.now().strftime("%y%m%d-%H_%M_%S.%f")
- daytime = daytime[:-3] # remove last three digits (xxx microseconds)
- daytime = daytime + "_" + str(countPixels)
- tstr = ("%s, %04.1f, %6.3f, %03d\n" % (daytime,max,interval,countPixels))
- print (tstr, end='')
- f.write(tstr)
- f.flush()
- if (interval > picHoldoff): # don't write images more quickly than picHoldoff interval
- imgName = daytime + ".jpg"
- cv2.imwrite(imgName, image) # save as an image
- else: # very first frame
- avgcol = image[:,:,1] # green channel, set the initial average to first frame
- avgdiff = avgcol / 20.0 # obviously a coarse estimate
- first_frame = False
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement