Coding a Home Intruder System / Motion Detector with Python

Learn how to detect motion, process and analyze images by coding your own security camera

Coding a Home Intruder System / Motion Detector with Python
(image by Alberto Rodriguez Santana on Unplash)

Analyzing and mining images and video streams for data can be extremely useful for many cases. In this article we’ll focus on a very basic technique: detecting motion in streams so that we can isolate the moving things and apply further analysis and/or detection.

The goal is to learn how motion-detection works and learn how to apply the required techniques so that you can use them in your own projects; think of image processing detecting movement and ways to display movement in the video stream. The end result of this article will be some code that can be applied as a home-intruder system or a wild-life camera for example. Let’s code!


Before we begin

Of course, when working with video streams there might be concern for data. Always take into account the potential risks of handling images in which persons are clearly visible. Check out the article below on how to mitigate potential risks handling this kind of data:

Detect and Blur Faces with a Simple Function — image analysis for beginners
Automatically anonymize your images, video’s or video-stream

The result

Let’s first check out what we’re working towards:

The end result (gif by author)

As you see we are able to detect whether movement was detected in the video and even isolate the movement (the green rectangle). Notice that very small movements like changing lights or swaying grass is ignored. In the next parts we’ll explore how this is done.

Why Python is so slow and how to speed it up
Take a look under the hood to see where Python’s bottlenecks lie

The strategy

We’ll create a screenshot every 10 seconds and compare each frame with that screenshot. If there are any differences we’ll display them by drawing a big, green rectangle around the area’s in which movement was detected. Also we’ll add a big red text that says “Movement detected!”.

The process can be described in these steps:

  1. Get a hold of the frames that the camera records
  2. Set the comparison frame; we’ll compare each following frame against this one so we can detect changes (i.e. movement)
  3. Analyze each frame: get the differences with the comparison frame
  4. Filter the differences: only take areas into account that are large enough
  5. Draw green rectangles around the differences
  6. Done!
Applying Python multiprocessing in 2 lines of code
When and how to use multiple cores to execute many times faster

Step 1. Reading video

We’ll use Python and a package called OpenCV and PIL (Python Image Lib). Install them like this:pip install opencv-python pillow

Now let’s set up some code that allows us to read frames. Since I want to create a nice-looking example I’ve chosen to record a part of my screen that displays a Youtube-video that shows how an intruder enters someone’s backyard. If you want to use your webcamera or some other camera I’ll refer you to the article below.

How to read images, video, webcam and screen in OpenCV — image analysis for beginners
Step by step guide on how to read images for OpenCV to process

Because I record only a part of my screen I need the screenTOP, screenBOT etc. arguments so that I can ‘Imagegrab’ (screenshot) them nicely:

We’ll skip to LINE X where we read the frames. The code before will become clear in the next parts. We start an infinite while loop and use ImageGrab to create a screenshot that we’ll convert to a Numpy-array. This is an array that holds the RGB-values for each pixel in the screenshot.

Keep your code secure by using environment variables and env files
Securely load a file containing all of our app’s required, confidential data like passwords, tokens, etc

Part 2: Pre-processing

In this part we’ll prepare the images for detecting motion in.

OpenCV works by default with BGR (check out the article above) so we’ll need to convert BGR to RGB. We’ll need img_rgb later because we want to display it. The next two lines involve converting the RGB image to black and white. This is because the pixel-array now only needs to ‘hold’ one value (degree of blackness) in stead of three (red, green and blue). Lastly we blur the image a bit so very small differences are less noticeable.

Create a fast auto-documented, maintainable and easy-to-use Python API in 5 lines of code with…
Perfect for (unexperienced) developers who just need a complete, working, fast and secure API

Part 3. Comparing images

First we’ll have to set the comparison frame because we need something to compare our frames against. We’ll to this every 10 seconds (this is what the strt_time from part 1 is for.

Next we use a cv2 function called absdiff. This subtracts the pixel-values (the ‘degree of blackness’) of the current frame from the comparison-frame. The result looks like this:

How our video differs from the comparison-frame (gif by author)

Values that differ from the comparison-frame turn white; the rest is black.


Part 4. Filtering

Maybe sometimes a branch moves, clouds move in front of the sun or a piece of trash blows across the street. We don’t want every minor difference to trigger our alarm system.

In this code it’s determined that the color-difference of each pixel must be at least 20 (out of 255). Every pixel that meets this threshold will turn 100% white, the rest will turn 100% black.

Destroying Duck Hunt with OpenCV — image analysis for beginners
Write code that will beat every Duck Hunt high score

Part 5. Visual feedback

This is the best part. We have analyzed our images and now it’s time to draw conclusions (pun intended).

First we’ll find all contours, these are the areas of the threshold-frame that can be grouped together. Think of a contour as the fill-bucket in MS paint.

Next we’ll loop through each contour and, if the area is large enough, we’ll calculate the bounding rectangle around the contour. We’ll use that to draw the green rectangle around the contour. Also we insert a text if there is at least one contour that is large enough. Notice that we draw the rectangles and text on the img_rgb frame we saved earlier.

The last part is to show the results.

(gif by author)

Conclusion

With this article I hope to have demonstrated a few ways to prepare, process and analyze images for you to extract and analyze data from images. You can find the full code for this article here.

I hope this article was as clear as I hope it to be but if this is not the case please let me know what I can do to clarify further. In the meantime, check out my other articles on all kinds of programming-related topics like these:

Happy coding!

— Mike

P.S: like what I’m doing? Follow me!

Join Medium with my referral link - Mike Huls
Read every story from Mike Huls (and thousands of other writers on Medium). Your membership fee directly supports Mike…