The problem with motion detection
When a modern CCTV camera/NVR detects motion, it can save still frames of the image and, if configured to do so, will email those images to one or more addresses. This can lead to many false-alarms, however, which will often result in the recipient disregarding what could be, at any given moment, a very serious problem.
My solution so far
To that end, I’ve taken up the task of writing a Python script, utilizing OpenCV’s computer vision libraries, that will process and curate the images generated by an NVR. The script will determine if the generated images contain faces of people. If the images do not contain faces, then I won’t be sent an email alert. If the image does include a face, then I will indeed receive an email with that image attached. This should make alerts more useful, and result in fewer false-alarms so that we can avoid a boy-who-cried-wolf scenario.
The benefits of Python
Some NVRs and IP Cameras already feature facial-detection capabilities, but what if yours does not? This script runs independent of your CCTV equipment, providing modularity and saving you from hardware upgrade expenses. Given the nature of Python, this can be run from virtually any operating system you might be using.
Things I’d still like to add
- Improve file-selection and saving
- Implement batch processing
- Add capability to detect facial profiles
- Add capability to detect full body, lower body, and upper body
- Add graphical user interface
import numpy as np import sys import cv2 import matplotlib face_cascade = cv2.CascadeClassifier('c:\\opencv\\build\\etc\\haarcascades\\haarcascade_frontalface_default.xml') eye_cascade = cv2.CascadeClassifier('c:\\opencv\\build\\etc\\haarcascades\\haarcascade_eye.xml') full_body = cv2.CascadeClassifier('c:\\opencv\\build\\etc\\haarcascades\\haarcascade_fullbody.xml') upper_body = cv2.CascadeClassifier('c:\\opencv\\build\\etc\\haarcascades\\haarcascade_upperbody.xml') selected_image = raw_input('Enter a file for processing: ') img = cv2.imread(selected_image) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, 1.3, 5) for (x,y,w,h) in faces: img = cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2) roi_gray = gray[y:y+h, x:x+w] roi_color = img[y:y+h, x:x+w] eyes = eye_cascade.detectMultiScale(roi_gray) for (ex,ey,ew,eh) in eyes: cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2) cv2.imshow('img',img) k = cv2.waitKey(0) if k == 27: # wait for ESC key to exit cv2.destroyAllWindows() elif k == ord('s'): # wait for 's' key to save and exit saveas = raw_input('Save file as: ') cv2.imwrite(saveas+'.jpg',img) cv2.destroyAllWindows() sys.exit()