This is a cool project that uses computer vision techniques and a webcam to act as a security system. I will demonstrate how to detect if a door is opened then have my computer yell at the opener. For this all you need is a webcam, python, and the modules opencv and pyttsx.

A brief overview:

  • Use background subtraction to see if the door gets moved
  • Then have the pyttsx module make your computer say whatever you want at the person who opened it
The opencv background subtractors weren't working for me so I made my own.

Door Movement

Opencv has a nice tutorial on their background subtractor, but I'll be using the one I made. Grabbing a frame from the webcam, putting it into the background subtractor, then displaying it looks something like this
import background_subtractor
import cv2
import numpy as np
import video

cap=video.create_capture(0)           #get your webcam

#####wait until a good frame comes in####
ret=False
while not ret:
    ret, frame=cap.read()
#########################################

frame=cv2.cvtColor(cap.read()[1], cv2.COLOR_BGR2GRAY)

bs=background_subtractor.BackgroundSubtractor(frame)

while True:
    frame=cv2.cvtColor(cap.read()[1], cv2.COLOR_BGR2GRAY)      #get a grayscale frame from webcam

    foreground_mask=bs.apply(frame)

    cv2.imshow("frame", frame)
    cv2.imshow("mask", foreground_mask)

    k=cv2.waitKey(10)               #delay 10 miliseconds and get key press
    if k==1048690:                  #the 'r' key; will probably be 114 for you
        bs.update_reference_frame()
    if k==1048603:                  #the 'esc' key; will probably be 27 for you
        cv2.destroyAllWindows()
        quit()
                

And now we can see when the door opens!  But how do we get the computer to know?  First we'll start off by slicing the frame to get just the door.

Adding

door_slice=frame[100:480,400:640]
mask_slice=foreground_mask[100:480,400:640]

cv2.imshow("door slice", door_slice)
cv2.imshow("mask slice", mask_slice)
                

to the inside of the loop gives

From here, all we have to do is count the number of white pixels to see if the door is open.  Since the dimensions of the image we're using are 380x240 (from the slice; 480-100, 640-400), the total number of pixels is 91200.   So I chose a threshold of 80000 for the door being open, meaning if the number of while pixels is greater than 80000, consider the door to be open.
if np.cumsum(mask_slice)[-1] > 80000:
print "DOOR IS OPEN"
                

Make It Talk!

All we have to do now is use the text to speech module. To do so, add

import pyttsx

engine=pyttsx.init()
talked=False
                

to the top of the code around the other imports. Then switch out the

print "DOOR IS OPEN"
                
line with
if not talked:
    engine.proxy._driver.say("Go away!")
    talked=True
else:
    if talked:
        talked=False
                

(or whatever else you want it to say inside the quotes).  The talked variable makes it so it only talks once each time the door opens and doesn't keep repeating.  And if you're wondering where the proxy._driver came from, the original pyttsx API wasn't working properly so I had to do some reverse engineering on it.

Time to test it out

...Not the most convincing voice. It'd be better by playing an audio file of a dog barking or something like that(and python even has a module for reading WAV files), but I'm happy with it right now.