In my last 2 articles, I have shared with you code from my home automation system (HAS) controller written in Python that allows you to access your Google Calendar for scheduling events and communicating with the Insteon PowerLinc USB modem for controlling your Insteon and X10 HAS devices from Raspberry Pi (or other dedicated computer).
In today’s article, I want to share with you some Python code that uses OpenCV to detect faces from the Insteon (or FOSCAM) IP Camera which you can get from SmartHome.com for about $79. At my house, I use this code to detect when my fiancee or I approach one of the exterior doors. When we do, my HAS will recognize us and will automagically unlock the door that we are approaching. To do that, I am using the MiLocks 3-in-1 deadbolt system which is also available at SmartHome.com and will run you about $100 per lock. You will also need the MorningLinc Insteon adapter which will allow you to communicate with the MiLocks deadbolts over RF. These are also available from SmartHome.com and will run you about $50. You will only need 1 which is capable of controlling multiple locks.
Before I share the code, I should say that this particular code does NOT include the ability to recognize one person from another like that found in my personal HAS controller. All this code is capable of doing is detecting a face and saving a screenshot of that face to the file system (regardless who the face belongs to). The reason I am not sharing the face matching code yet is because there are a lot of complex steps required to train the system to detect individuals. I am currently working on a way to simplify these tasks. It took me several weeks to prepare the system manually for recognizing my fiancee and I with an acceptable accuracy and to not unlock our doors due to any false positives. Once I get this process simplified, I will share the code.
In order for this code to work, there are a few things you will need to do to prepare. First, you will need to install the Insteon (or FOSCAM) IP Camera and have it running & accessible from your Raspberry Pi – the camera and the Raspberry Pi should both be on the same network.
Next, you are going to need to install the OpenCV dependencies on your Raspberry Pi. If you haven’t done that before, you can learn how by clicking here.
Once you have OpenCV installed on your Raspberry Pi, you will need a library that allows you to access your camera from Python. I could have (and plan to at some point) written my own library. But, I managed to find a decent library for the purposes of this article at https://code.google.com/p/foscam-with-python/. All you need from that project is “foscam.py”. To get it, just click on Source > Browse > foscam.py from the link above and save the file into the same folder you will be saving the code below.
Next, right-click on this link and select “Save As”. Save the file to the same folder as foscam.py and the code below. This file is an XML file called a “haar cascade classifier”. It’s basically a file that was trained on a list of images which tells OpenCV what a face “looks like”. This is the file that we will use to detect when a face has entered the field-of-view of the camera.
That’s it. You now have everything you need to detect faces from the Insteon (or FOSCAM) IP Cameras using Python and OpenCV. Make sure you set the IP address, username, and password of your camera in the code before running it.
Note: Even though this code doesn’t include the ability to recognize who the person is in the camera, it can still be used as-is to save pictures of people that approach your camera. It’s kinda like a system for motion detection, but takes it to the next step by actually detecting that there is a person within view and saving their picture to the file system.
Also, if you plan on unlocking your doors using the MiLocks and MorningLinc combo mentioned above, you will need to checkout my last article about communicating with Insteon hardware using Python, the Raspberry Pi, and the Insteon PowerLinc USB modem. You will need to use the address of the MorningLinc adapter in the code from that article for sending commands to your MiLocks deadbolts.
from PyQt4.QtGui import * from PyQt4.QtCore import * import sys import foscam import Image from StringIO import StringIO import time import cv2 ImageReadyEventId = 1382 faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_alt2.xml') class ImageReadyEvent(QEvent): def __init__(self, image): QEvent.__init__(self, ImageReadyEventId) self._image = image def image(self): return self._image class IPCam(): def __init__(self): self.foscam = foscam.FoscamCamera('[IP ADDRESS]', '[USERNAME]', '[PASSWORD]') def up(self): self.direction = self.foscam.UP self.foscam.move(self.direction) def down(self): self.direction = self.foscam.DOWN self.foscam.move(self.direction) def left(self): self.direction = self.foscam.LEFT self.foscam.move(self.direction) def right(self): self.direction = self.foscam.RIGHT self.foscam.move(self.direction) def stop(self): self.foscam.move(self.direction + 1) def playVideo(self): self.foscam.startVideo(videoCallback, self) def stopVideo(self): self.foscam.stopVideo() def event(self, e): if e.type() == ImageReadyEventId: data = e.image() im = Image.open(StringIO(data)) self.qim = QImage(im.tostring(), im.size, im.size, QImage.Format_RGB888) self.pm = QPixmap.fromImage(self.qim) #self.image_label.setPixmap(self.pm) #self.image_label.update() with open('picture.png', 'wb') as f: f.write(self.pm) return 1 return QWidget.event(self, e) import numpy as np def videoCallback(frame, userdata=None): nparr = np.fromstring(frame, np.uint8) img = cv2.imdecode(nparr, cv2.CV_LOAD_IMAGE_COLOR) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) faces = faceCascade.detectMultiScale( gray, scaleFactor=1.1, minNeighbors=5, minSize=(30,30), flags = cv2.cv.CV_HAAR_SCALE_IMAGE ) for (x, y, w, h) in faces: cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2) print 'Found face' #with open('picture.png', 'wb') as f: # f.write(img) cv2.imwrite('picture.png', img) if __name__ == '__main__': cam = IPCam() cam.playVideo() time.sleep(1) cam.stopVideo()
PayPal will open in a new tab.