Foundation forum member ‘brainflakes‘ has managed to write a Python script to take and analyse images from the Raspberry Pi camera module in order to detect movement. He explains what it does on the forum:
While watching for motion it pipes a thumbnail image from raspistill at around 1fps to analyse (it keeps everything in memory to avoid wearing out the SD card). Once motion is detected it calls raspistill again to write a high-res jpeg to disk.
It also checks free disk space and if under a set limit it starts to delete the oldest images to make sure there is always enough free space for new images.
While running on my rev1 B it consumes around 12% CPU / 4% ram and manages to capture a full size image once ever 2-3 secs.
If you need to install PIL run “sudo aptitude install python-imaging-tk”
Here’s the script:
import StringIO import subprocess import os import time from datetime import datetime from PIL import Image # Motion detection settings: # Threshold (how much a pixel has to change by to be marked as "changed") # Sensitivity (how many changed pixels before capturing an image) # ForceCapture (whether to force an image to be captured every forceCaptureTime seconds) threshold = 10 sensitivity = 20 forceCapture = True forceCaptureTime = 60 * 60 # Once an hour # File settings saveWidth = 1280 saveHeight = 960 diskSpaceToReserve = 40 * 1024 * 1024 # Keep 40 mb free on disk # Capture a small test image (for motion detection) def captureTestImage(): command = "raspistill -w %s -h %s -t 0 -e bmp -o -" % (100, 75) imageData = StringIO.StringIO() imageData.write(subprocess.check_output(command, shell=True)) imageData.seek(0) im = Image.open(imageData) buffer = im.load() imageData.close() return im, buffer # Save a full size image to disk def saveImage(width, height, diskSpaceToReserve): keepDiskSpaceFree(diskSpaceToReserve) time = datetime.now() filename = "capture-%04d%02d%02d-%02d%02d%02d.jpg" % (time.year, time.month, time.day, time.hour, time.minute, time.second) subprocess.call("raspistill -w 1296 -h 972 -t 0 -e jpg -q 15 -o %s" % filename, shell=True) print "Captured %s" % filename # Keep free space above given level def keepDiskSpaceFree(bytesToReserve): if (getFreeSpace() < bytesToReserve): for filename in sorted(os.listdir(".")): if filename.startswith("capture") and filename.endswith(".jpg"): os.remove(filename) print "Deleted %s to avoid filling disk" % filename if (getFreeSpace() > bytesToReserve): return # Get available disk space def getFreeSpace(): st = os.statvfs(".") du = st.f_bavail * st.f_frsize return du # Get first image image1, buffer1 = captureTestImage() # Reset last capture time lastCapture = time.time() while (True): # Get comparison image image2, buffer2 = captureTestImage() # Count changed pixels changedPixels = 0 for x in xrange(0, 100): for y in xrange(0, 75): # Just check green channel as it's the highest quality channel pixdiff = abs(buffer1[x,y][1] - buffer2[x,y][1]) if pixdiff > threshold: changedPixels += 1 # Check force capture if forceCapture: if time.time() - lastCapture > forceCaptureTime: changedPixels = sensitivity + 1 # Save an image if pixels changed if changedPixels > sensitivity: lastCapture = time.time() saveImage(saveWidth, saveHeight, diskSpaceToReserve) # Swap comparison buffers image1 = image2 buffer1 = buffer2
Many thanks to brainflakes for this – fantastic to see people getting stuck in with some useful applications for the camera
[…] recantha Foundation forum member ‘brainflakes‘ has managed to write a Python script to take and analyse […]
Hi…thanks for this post!….wanted to know if this script will work with other USB cameras?!
@Kevin. it would work with other cameras yes.
You would need to modify the captureTestImage() function.
there are a few ways to achieve this. Including using pygame. or opencv.
I would suggest searching “capturing images from webcams in python” and you should find a few tutorials. then replace the captureTestImage() with the image acquiring code from the tutorials. As long as it returns an image and an image buffer, the rest of the code should work fine.
[…] ใช้กล้องของ Raspberry Pi จับว่าเมื่อไหรที่ภาพมีการเปลี่ยนแปลงครับ แต่แทนที่จะใช้ Motion เพื่อดักจับความเปลี่ยนแปลง ก็เขียนสคริป Python แทน โดยใช้ Python Image Library (PIL) มาช่วยดึงภาพจากสองเวลา แล้วเทียบกันว่า pixel เปลี่ยนไปกี่จุด ถ้ามากพอจึงจะถือว่าภาพเกิดการเปลี่ยนแปลง แล้วก็ใจดีแจก source code มาด้วยครับ ที่มา Raspberry Pi ผ่านทาง http://178.62.14.192/?p=4296 […]
Hi,
This is a great post had it working for some time but recently it just stopped altogether and wont capture any images. I have checked and the camera still works fine. It halts on the line
imageData.write(subprocess.check_output(command, shell=True))
And the error text includes a reference to
“/usr/lib/python2.7/subprocess.py”,
I think this started after I upgraded recently (sudo apt-get upgrade). Do you know of an issue that might cause this?
Thanks
Dave