Adding Face Detection to your Pi Powered Motion Detector
Back during //Build 2015 I was playing with the Project Oxford APIs — Microsoft’s computer vision platform, now called Azure AI Vision — and in parallel building some Raspberry Pi based AllJoyn projects. I ended up combining them: a Pi running the Motion app as a security camera, with a hook that sends every captured frame through Oxford’s face detection API.
Here’s how to build your own.
Hardware and software you need
- Raspberry Pi (any model with a camera connector)
- Pi Camera module or USB webcam
- WiFi adapter (if your Pi doesn’t have built-in WiFi)
- A Project Oxford / Azure AI Vision API key
Step 1: Get the Pi running
- Install Raspberry Pi OS on an SD card
- Connect camera, WiFi adapter (if needed), SD card
- Boot, run
raspi-config— enable SSH, camera, set WiFi credentials - Configure wireless if not done in raspi-config
Update everything and install Motion:
1
2
3
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install motion
Step 2: Hook Motion to the face detector
Motion has a configuration directive that runs a shell script whenever it captures a frame. Edit /etc/motion/motion.conf — around line 510 you’ll find the on_picture_save directive:
1
2
3
# Command to be executed when a picture (.ppm|.jpg) is saved (default: none)
# To give the filename as an argument to a command append it with %f
on_picture_save sh /home/pi/oxford/motion-picture-save.sh %f
This tells Motion to call your script with the captured filename every time motion is detected.
Step 3: The shell script
Create /home/pi/oxford/motion-picture-save.sh:
1
2
3
#!/usr/bin/env bash
echo $1
/usr/bin/python /home/pi/oxford/oxford.py $1
Make it executable:
1
chmod +x /home/pi/oxford/motion-picture-save.sh
Step 4: The face detection script
Create /home/pi/oxford/oxford.py. This sends the captured image to the Oxford face detection API and prints what it finds:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/usr/bin/env python
import sys
import urllib
import json
import requests
url = "https://api.projectoxford.ai/face/v1.0/detect"
headers = {
'Content-type': 'application/octet-stream',
'Ocp-Apim-Subscription-Key': 'YOUR_API_KEY_HERE',
}
params = {
'returnFaceAttributes': 'age,gender,headPose',
'returnFaceLandmarks': 'true',
}
if len(sys.argv) == 2:
filename = sys.argv[1]
else:
print("Usage: oxford.py <image_file>")
sys.exit(0)
payload = open(filename, "rb").read()
try:
resp = requests.post(url, params=params, data=payload, headers=headers)
faces = resp.json()
if faces:
for face in faces:
attrs = face.get('faceAttributes', {})
print("Face detected — age: {age}, gender: {gender}".format(**attrs))
else:
print("No faces detected")
except Exception as e:
print("Error: {0}".format(str(e)))
Install the dependencies:
1
pip install requests
Step 5: Run it
Start Motion:
1
sudo motion
Walk in front of the camera. Motion captures a frame, calls your shell script, which calls oxford.py, which hits the API and prints face attributes to the log. You’ll see output like:
1
Face detected — age: 38, gender: male
What this is actually useful for
On its own, printing to a log isn’t that interesting. But this is a skeleton you can build on:
- Notify on unknown faces — store known face IDs and alert if a stranger is detected
- Count people — track how many distinct faces appear over time
- Log to a database — store detections with timestamps for later analysis
- Push to Nitrogen or another IoT platform — stream detections as events
The Oxford/Azure Face API also returns face landmarks, emotion attributes, and can do face identification if you train it with a person group. The Python client library I wrote at the time wraps all of this cleanly if you want to go further than raw REST calls.
The Pi + Motion combination is solid for a low-cost always-on camera. Adding cloud vision on top of it is what turns it from a dumb motion sensor into something actually useful.