Simple Motion Detection

Harshit Patel
6 min readMay 25, 2021

The Goal

To be honest, I’m surprised it was this easy. It only took 24 lines of code (unspaced) to make a simple algorithm that can show boxes around moving objects.

Ball and stick being tracked

The code is also surprisingly simple. The original intention of this project was to be something that would resemble an autonomous vehicle’s technology. I have come to learn that autonomous vehicles use a lot more complex technologies. Obviously, I didn’t walk into this believing I would make the next Tesla car in a week or two but I’ve learnt how complex this new technology can get. Autonomous vehicles use Convolutional Neural Networks (CNN’s) which are super complex AI’s that can detect what’s in an image. Some vehicles like the Waymo car use even more complicated technologies like LiDAR and RADAR sensors. I highly encourage you to look into these technologies if you find this project interesting.

Code Breakdown

That’s really all I had to write to get this project to work! I can’t help you on how to get started with writing the code but if you can get OpenCV (cv2) installed, you should be able to get all of this code working. I recommend using Pycharm because it is a lot more beginner/user friendly than some other code editors. You can use any video instead of test.mp4 or even a live camera just make sure it is in your project’s repository.

Lines 1–4

Line 1 imports the package into the file. The package OpenCV goes by the name cv2 in code. Line 2 reads the video we are using (test.mp4) and defines the video as cap. For this article I am writing 0 instead of a video which will set cap as my camera. Lines 3 and 4 define the first and second frames of the video as frame1 and frame2.

Line 5

This line sets the next lines to run on loop as long as the video is running.

Lines 6–10

This is where the fun begins! Line 6 finds the difference between the first and second frames. It would look like this:

cv2.COLOR_BGR2GRAY converts diff into grayscale. This just makes it easier to work with. Instead of having each pixel as a BGR data point (with 3 color values per pixel), we can store it as a black and white data point (only 1 value per pixel).

The 8th line blurs this image we have. Blurring the image makes it so that the less important spots like smudges on my nose or eyes are less visible and darker. Only the important details must be bright for the next step.

This creates a threshold or a selection that selects all the pixels specified. If you increase the first value (20) it will only select brighter pixels. If you decrease that value, it will pick up some of the smaller details.

cv2.dilate() simply makes the threshold larger so the selected details are accentuated

Lines 11–17

This is the part where the real magic is! Line 11 creates a list called contours. Contours basically select a region of connected or close parts and call it a contour (meaning outline). “for contour in contours” makes a loop that repeats the next lines for every contour in the list. Every time it loops, it selects a different contour. Line 13 defines the x and y positions, width, and height of a rectangle that would go around the contour. This rectangle is called a bounding box (hence the command, cv2.boundingRect).

The next 2 lines basically say that if the bounding box is larger than a certain area, the code may continue. This section is important because it stops you from getting a bunch of tiny rectangles everywhere pointing out the tiniest movements in your eyes or changes in skin tone. Line 16 actually draws the bounding boxes. The next line isn’t mandatory but it creates the sign in the top left that shows if something is moving or not. The final result should look something like this.

So far you’ve learned how to create the algorithms but you probably haven’t had any luck displaying your video.

cv2.imshow() displays the actual video. The bounding boxes have been drawn on frame 1 so we put frame 1 as the variable we are showing. Don’t worry about “feed”. That’s just the name of the window your video will be shown on. You can change it to whatever you want, just make sure to keep it in quotes.

These lines will update the frames so now frame1 is the second frame and frame2 becomes the third frame. Remember, we are still inside the while loop so everything we did from line 6 and on repeats every frame.

This part states that if the button q is pressed, stop the loop. The whole 0xFF thing is a bit complicated but if you just go along with the code it works fine.

This is written outside the while loop. Once the loop has been stopped this code will run. cv2.destroyAllWindows() closes the window displaying your video and cap.release() stops the video/camera.

You can fiddle with the numbers to get the sensitivities just right for whatever your needs are but that's it! This project was really fun to work on because it felt easy but complicated enough to give a sense of accomplishment. I highly recommend continuing researching into this area of programming. This tutorial is a great one that I used to learn how to use openCV.

--

--