Let's dive right in to the wonderful world of motion detection!
The basic idea of motion detection is pretty simple from a computer's point of view—the motion detection software processes a continuous stream of images and analyzes the positions of the pixels that make up the image. If a group of contiguous pixels above a certain threshold starts to change from one frame to the next, that must be something moving. The tricky part of motion detection is weeding out false positives triggered by naturally occurring changes in light and weather conditions.
pi@raspberrypi ~ $ sudo apt-get install motion
/etc/motion
directory. We will use this configuration file as a template and modify it for our needs. pi@raspberrypi ~ $ mkdir .motion
/etc/motion
into your new directory: pi@raspberrypi ~ $ sudo cp /etc/motion/motion.conf ~/.motion
chown
command: pi@raspberrypi ~ $ sudo chown pi:pi ~/.motion/motion.conf
pi@raspberrypi ~ $ nano ~/.motion/motion.conf
Motion has plenty of options to explore, and it's easy to be overwhelmed by them all. What we're aiming for, at this point, is to get a basic demonstration setup going with as few bells and whistles as possible. Once we've established that the main motion detection functionality is working as expected, we can move on to the advanced, extra features of Motion.
Apart from the regular, helpful comments preceded by the #
character, the ;
character is used to make individual configuration directives inactive. ; tunerdevice /dev/tuner0
, for example, means that the line will be ignored by Motion.
We will now go through the configuration directives and pause to explain or change options, from top to bottom:
videodevice
, v4l2_palette
, width
, height
, and framerate
: It is indeed important to update these directives if you want Motion to grab video directly from your webcam. However, we will not be doing this. Instead, we will be feeding the video stream that we have already set up with MJPG-streamer, into Motion. We will do this for three reasons:netcam_url
: Uncomment and change the line to read netcam_url http://localhost:8080/?action=stream
.The netcam_url
directive is used to feed network camera feeds into Motion, like our MJPG-streamer feed. Since we're running MJPG-streamer on the same machine as Motion, we use localhost
instead of the IP address of the Pi.
netcam_http
: Uncomment and change this to netcam_http 1.1
to speed up the communication with MJPG-streamer.gap
: Change value to 2
for this initial setup. This will be the number of seconds it takes for our alarm to reset as we're testing the system.output_normal
: Change to off
for now, as we don't need any JPG snapshots to be stored until we have everything set up.ffmpeg_cap_new
: Change this to off
during setup; we don't need any movies to be written either, until we have everything set up.locate
: Change to on
for our initial setup, because it'll help us understand the motion detection process.text_changes
: Also change to on
for our initial setup as it'll help us dial in the sensitivity.webcam_maxrate
: Change this value to match the frame rate of your MJPG-streamer video feed.webcam_localhost
: You'll need to change this to off
, because we'll be monitoring the webcam from another computer and not from the Pi.control_port
: This value needs to be changed to 7070
(or any number you like, above 1024
) because it's currently conflicting with the port we're using for MJPG-streamer.control_localhost
: Also needs to be changed to off
as we'll be accessing Motion from another computer and not from the Pi.on_event_start
: Uncomment and change the line to read on_event_start speaker-test -c1 -t sine -f 1000 -l 1
. This is our temporary alarm sound. Don't worry, we'll find something better in a minute.That's it for now; press Ctrl + X to exit, press y when prompted to save the modified buffer, and then press Enter to confirm the filename to write to.
All right, let's take our Motion system out for a spin!
-b
flag, as shown in the following command:pi@raspberrypi ~ $ mjpg_streamer -b -i "input_uvc.so -r 640x480 -f 30" -o "output_http.so -w /usr/www"
Note the number in parenthesis that mjpg_streamer
provides when forking to the background. This is called a Process ID (PID), and can be used to stop the mjpeg_streamer
application by passing it to the kill
command:
pi@raspberrypi ~ $ kill [PID]
You can explore all processes running on your Pi using the following command:
pi@raspberrypi ~ $ ps aux
pi@raspberrypi ~ $ motion
Press Ctrl + C at any time, to quit Motion.
http://[IP address]:8081
.You should be looking at your feed from MJPG-streamer, but with a few key differences—a clock in the lower-right corner, and the number of changed pixels in the upper-right corner. If you're looking, instead, at a gray image with the text unable to open video device, there's most likely a problem with MJPG-streamer or the netcam_url
line.
Studying the number of changed pixels is one of the best ways to understand the motion detection system. The number will spike whenever you move the camera, but should come to a rest at zero as Motion learns about light sources and applies an automatic noise filter to minimize the risk of false positives.
threshold
value (1500
by default) set in the configuration file, an event will fire, which is currently set to play the high-pitched tone. When no motion has been detected for the number of seconds specified by the gap
value (60
by default, currently 2
), the event ends and a new event may begin.http://[IP address]:7070
in the address bar.What you're seeing here is a simple web admin interface to control Motion. When we hook up more than one webcam to Motion, each camera will have its own thread and configuration, but right now there's only one thread and one configuration labeled All. Click on this to proceed.
http://[IP address]:8081
); you'll be viewing the camera in setup mode. Now wave your hand in front of the webcam again; you'll see the largest areas of changed pixels highlighted in blue, and minor changes in gray tones. You'll also notice three counters—D: for difference in pixels, L: for labels (connected pixel areas), and N: for noise-level.The configuration directives you'd want to tweak if you find that the motion detection is performing poorly can all be found under the Motion Detection Settings section of the configuration file.
Now that we've established an initial working Motion setup, we have to decide what actions we want the system to take upon detection. Sounding an alarm, saving images and videos of the detected activity, logging the activity to a database, or alerting someone via e-mail are all valid responses to detection.
Let's create a directory to hold our evidence:
pi@raspberrypi ~ $ mkdir ~/evidence
We're going to revisit the configuration file, but this time, we're setting up the system for use in the real world. Once again, we'll go through the configuration file and pause to explain or change options, from top to bottom. You'll need to type in the following command first to open the file for editing:
pi@raspberrypi ~ $ nano ~/.motion/motion.conf
gap
: We're changing this back to the default 60
seconds.output_normal
: Change this to best
to save a JPG snapshot when the biggest change in motion occurs. We're also going to record a movie, so you won't miss anything.ffmpeg_cap_new
: Change this to on
to record a movie of the event that triggers the detection.ffmpeg_video_codec
: Change this to mpeg4
to get a video that can be played back on the Pi itself with OMXPlayer, or on another computer with VLC.locate
: Change this back to off
, as we don't want a rectangle drawn onto our evidence.text_changes
: Same for this one; change it back to off
for cleaner video output.target_dir
: Change this to our newly created /home/pi/evidence
directory.webcam_maxrate
: Change this back to 1
to lower the CPU usage. We can still directly watch the MJPG-streamer feed at 30 FPS.on_event_start
: It's up to you whether you want to keep the alarm tone. Why not record a better one yourself with Sound eXchange (SoX)—perhaps a robot voice saying "intruder alert!"—and then play it back with a simple sox
command.Now if you start Motion again and trigger a detection, a video file will start recording the event to your ~/evidence
directory, and after the 60-second gap, a JPG snapshot with the largest change in motion will be written to the same location.
Whenever a new file is recorded, the filename will be announced in the Motion console log:
[1] File of type 8 saved to: /home/pi/evidence/01-20130127111506.avi [1] File of type 1 saved to: /home/pi/evidence/01-20130127111526-04.jpg
To view the videos on the Pi itself, use omxplayer
and specify a filename:
pi@raspberrypi ~ $ omxplayer ~/evidence/01-20130127111506.avi
Before we view the images, we need to install the FIM (Fbi IMproved) image viewer:
pi@raspberrypi ~ $ sudo apt-get install fim
Now we can start fim
and point it to an individual image (by specifying its filename) or a collection of images (by using the wildcard asterisk character):
pi@raspberrypi ~ $ fim ~/evidence/*.jpg
Press Enter to show the next image, and press Q to quit fim
.
If you've got an extra webcam at home, perhaps built into a laptop, it would be a shame not to let it help out with the motion detection mission, right?
We're going to look at how to connect more camera streams to Motion. These streams might come from conventional IP security cameras, but the same method works equally well for webcams on Windows and Mac computers, with some tinkering.
We'll be using webcamXP to add additional cams in Windows:
wlite551.exe
, at the time of writing). webcamXP is free for private use (single video source).[WinIP]
to the IP address of your Windows computer:http://[WinIP]:8080/cam_1.cgi
We'll be using VLC to add additional cams in Mac OS X:
Applications
folder.qtcapture://
followed by the ID number of your particular webcam. You will need this string later. Click on the Stop button to be able to see it clearly in the playlist. From the Window drop-down menu, select Media Information…, where you will be able to copy the string./Applications/Utilities
) and type in the following command, replacing [ID]
with the ID of your webcam and adjusting the width and height to suit your webcam:/Applications/VLC.app/Contents/MacOS/VLC qtcapture://[ID] --qtcapture-width 640 --qtcapture-height 480 --sout='#transcode{vcodec=mjpg}:duplicate{dst=std{access=http{mime=multipart/x-mixed-replace;boundary=--7b3cc56e5f51db803f790dad720ed50a},mux=mpjpeg,dst=:8080/stream.mjpg}}'
VLC will start serving a raw M-JPEG stream over HTTP on port 8080
, suitable for feeding into Motion.
http://[MacIP]:8080/stream.mjpg
in the address bar, but change [MacIP]
to the IP address of your Mac.To incorporate our new webcam stream into Motion, we will need to rework the configuration so that each camera runs in its own thread. We do this by taking all the configuration directives that are unique to each webcam and putting them in separate configuration files: ~/.motion/thread1.conf
for camera one, ~/.motion/thread2.conf
for camera two, and so on.
thread1.conf
:thread2.conf
:~/.motion/motion.conf
. At the bottom of the file, you'll find the thread directives. Change two of them to include your new thread configurations:thread /home/pi/.motion/thread1.conf
thread /home/pi/.motion/thread2.conf
As a final touch, you can uncomment the text_left
configuration directive to enable text labels that'll make it easier to tell the camera feeds apart.
Now visit http://[IP address]:7070
, and you'll see that the initial web admin menu makes more sense. The feed of camera one is available at http://[IP address]:8081
, and for camera two at http://[IP address]:8082
.
The only thing missing from our motion detection system is a proper villain's lair security monitoring wall! We can easily throw one together using basic HTML, and serve the page with the tiny HTTP server already running with MJPG-streamer.
Let's add and edit our custom HTML document, with the following command:
pi@raspberrypi ~ $ sudo nano /usr/www/camwall.html
Use this code template and replace [IP address]
with the IP address of your Raspberry Pi:
<!DOCTYPE html> <html> <head> <title>Motion Camera Wall</title> <style> img{border:black solid 1px; float:left; margin:0.5%;} br{clear:both;} </style> </head> <body> <img src="http://[IP address]:8081/" width="320" height="240"/> <img src="http://[IP address]:8082/" width="320" height="240"/> <br/> <img src="http://[IP address]:8083/" width="320" height="240"/> <img src="http://[IP address]:8084/" width="320" height="240"/> </body> </html>
Adjust the number of img
tags to match the number of Motion threads. Feel free to increase the width and height values if your monitor resolution can fit them. Then save and exit nano
.
So what we've built here is a simple HTML page that shows four different video feeds on the same page in a grid-like pattern. You can see this in the following screenshot. Each <img>
tag represents one video camera.
Your security monitoring wall may now be admired at the following address:
http://[IP address]:8080/camwall.html
3.145.71.115