STEP 2: INSTALL THE USB WEBCAM
If you already have a USB webcam, then see if it works with the Raspberry Pi before you get another one. First, check whether the Raspberry Pi can detect your webcam as a USB device by entering the command lsusb in LXTerminal both before and after plugging the webcam into the Pi, without the USB extension lead.
$ lsusb
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 004: ID 03f0:e207 Hewlett-Packard
Bus 001 Device 006: ID 04d9:1603 Holtek Semiconductor, Inc. Keyboard
Bus 001 Device 005: ID 1c4f:0034 SiGma Micro
If an extra entry appears after you run the command with the webcam plugged in, then that entry should be your webcam. In the list I’ve shown, my Hewlett-Packard webcam is the fourth entry from the top.
If your webcam does not appear in the list, then try unplugging it, plugging it back in, and running the lsusb command again. If that doesn’t work, try a reboot of the Raspberry Pi.
Unfortunately, being recognized as a USB device is still no guarantee that a webcam will work with the Raspberry Pi. You’ll find out for certain when you run the program. You may also find that your webcam works only if it’s plugged into a powered hub. If you have an older model of Raspberry Pi, you may find instead that the whole board resets when you plug the webcam into the USB port. If this is the case for your board, then plug the webcam in while the Raspberry Pi is powered off.
STEP 3: INSTALL THE SOFTWARE
Connect the Raspberry Pi to your network with an Ethernet cable, make sure the Internet is up and running, and download the Raspberry Pi programs for the projects in this book. From your browser on the Pi, you can head to http://www.nostarch.com/zombies/, click the link to GitHub, and download the Raspberry Pi directory. For this project, you’ll use the code in the usb_webcam directory. But the easiest way to get the software onto your Raspberry Pi is to clone the GitHub repository directly onto your Raspberry Pi, as I describe in “Fetching Source Code from GitHub” on page 92.
The Python program monitor.py is pretty brief, considering what it does, and I’ll walk you through it here. I won’t, however, cover Python itself beyond the context of the projects that use it. If you are new to Python, you might take a look another of my books, Programming the Raspberry Pi: Getting Started with Python (McGraw-Hill, 2013).
FETCHING SOURCE CODE FROM GITHUB
You can get all the Raspberry Pi programs used in this book onto your Raspberry Pi in one go by cloning the book’s GitHub repository. Just enter the following commands from a terminal window on the Raspberry Pi.
$ cd /home/pi
$ git clone https://github.com/simonmonk/zombies.git
These commands will fetch all of code for the book, including the Arduino code used in other projects (which you can ignore in this chapter). Even though you’re not using a browser, you’ll still need an Internet connection for the commands to work, so definitely get this code before the apocalypse.
The program begins by importing the various Python modules that it needs. These libraries of existing code are all included in the Raspbian distribution, so you shouldn’t need to install them separately.
import sys
import time
import pygame
import pygame.camera
import RPi.GPIO as GPIO
The sys and time modules have general utilities for accessing the operating system and the ability to tell the program to sleep as a way of delaying its activity for a period of time. The pygame module contains the Pygame graphical games library, which includes a camera interface. To control the LED, the program needs access to the GPIO system, and this is provided by the RPi.GPIO library.
Next, the program defines some constants that it will use. You could change these if you wanted to use the camera at a different resolution or make the default size of the window larger.
camera_res = (320, 240)
window_size = (640, 480)
red_pin = 18
green_pin = 23
The parameters in parentheses after the camera_res and window_res constants are the width and height respectively (in pixels). After the constants, the Pygame system (used to display the camera images) and the camera itself are initialized, along with the GPIO ports that you’ll use to control the Raspberry Squid:
➊ pygame.init()
pygame.camera.init()
# initialize GPIO
➋ GPIO.setmode(GPIO.BCM)
GPIO.setup(red_pin, GPIO.OUT)
GPIO.setup(green_pin, GPIO.OUT)
➌ screen = pygame.display.set_mode(window_size, 0)
#Find, open, and start the low-res camera.
➍ cam_list = pygame.camera.list_cameras()
webcam = pygame.camera.Camera(cam_list[0], camera_res)
webcam.start()
➎ old_image = False
The first two lines of initialization code ➊ handle Pygame and the camera, while the next three lines ➋ initialize those GPIO ports. The screen is then initialized ➌ to the size of the window specified in window_size. The final cluster of lines ➍ first finds all the cameras connected to the Raspberry Pi and then creates a link to the first one (webcam). It then starts running the webcam. The final line ➎ defines a variable called old_image, which is used to detect movement by spotting changes in successive frames from the webcam.
After initialization, the first function this program defines is called check_for_movement.
def check_for_movement(old_image, new_image):
global c
diff_image = pygame.PixelArray(new_image)
.compare(pygame.PixelArray(old_image), distance=0.5,
weights=(0.299, 0.587, 0.114))
ys = range(0, camera_res[1] / 20)
for x in range(0, camera_res[0] / 20):
for y in ys:
if diff_image[x*20, y*20] > 0:
return True
return False
As the name suggests, check_for_movement takes two images, the previous frame (old_image) and the latest frame (new_image), and compares them. The distance parameter to compare is the “distance” between the color of the pixel in one image and the color of that same pixel in the other image. The weights parameter is not explained in the pygame documentation, and the values used here are taken in faith from an example in the pygame documentation for PixelArray (http://www.pygame.org/docs/ref/pixelarray.html).
The comparison results in a new image called diff_image that only has white pixels where a difference was found between the pixels in the two images.
To decide whether movement has occurred, the program should really go through every pixel in the diff_image. But any largish movement will result in lots of pixels changing, and zombies are big, so the code speeds things up by only sampling 1 pixel in 20.