Motion Detected Alarm System using OpenCV in Python

In this tutorial, we will learn how to build a motion detected alarm system using OpenCV in Python. We will learn how to detect any moving objects using the webcam and sound an alarm for any irregular movements.

We will be using two main libraries, namely, OpenCV and pyttsx3. To install these libraries using pip, use the commands given below:

pip install pyttsx3
pip install opencv-python
pip install threading

We will use OpenCV to detect any movement and pyttsx3 to create a sound alarm.

Python code for Motion Detected Alarm

First, let’s import the libraries that we installed.

import cv2
import pyttsx3
import threading

We will now set the voice properties for our alarm.

alarm_sound = pyttsx3.init()
voices = alarm_sound.getProperty('voices')
alarm_sound.setProperty('voice', voices[0].id)
alarm_sound.setProperty('rate', 150)

We are initializing our text to speech library (pyttsx3), and connecting to the voices available. There are two voices, male and female. We have selected male voice by using its index value, i.e. (“voices[0].id”).

Now, we will use OpenCV to use our webcam for motion detection. Before using our webcam we will set the first/initial frame to “None”.

status_list=[None,None]
initial_frame = None
video=cv2.VideoCapture(0)
while True:
    check, frame = video.read()
    frame = cv2.flip(frame,1)
    status=0

We have set a ‘None’ value for our initial frame. Then, video is captured from the webcam with the help of “cv2.VideoCapture” command. Now, we are reading the frames from the captured video in a while loop. To learn more about how to use OpenCV, visit OpenCV Tutorial.

gray_frame=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
gray_frame=cv2.GaussianBlur(gray_frame,(25,25),0)
blur_frame = cv2.blur(gray_frame, (5,5))

Here, we have converted our frame into gray color and made it a little blur.

if initial_frame is None:
        initial_frame = blur_frame
        continue

Since we kept our initial frame to “None” and if it remains the same, we are forwarding the blur_frame to our initial_frame. So, the blur_frame will be our initial frame.

delta_frame=cv2.absdiff(initial_frame,blur_frame)
threshold_frame=cv2.threshold(delta_frame,35,255, cv2.THRESH_BINARY)[1]

Here, we are finding the difference between our initial_frame and blur_frame and then converting it into a binary image by using a method called Image Thresholding. In this method, we specify a certain value in the function and if the pixel value of the image is greater than the specified value, that pixel is assigned the value of the white color(200). If the pixel value is lower than the specified value, that pixel is assigned the value of black color(0). In this way, we will get a binary image of two colors, white and black. This binary image is now used to find the contour around the detected object.

(contours,_)=cv2.findContours(threshold_frame,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
for c in contours:
        if cv2.contourArea(c) < 5000:
            continue
        status=status + 1
        (x, y, w, h)=cv2.boundingRect(c)
        cv2.rectangle(frame, (x, y), (x+w, y+h), (0,255,0), 1)
    status_list.append(status)

Now, we are finding the contours by using the threshold_frame. We have specified that, if the contour area is greater than 5000, a rectangle box is drawn around the object. We are then updating our status_list by appending the status value into it.

if status_list[-1]>= 1 and status_list[-2]==0:
        alarm = threading.Thread(target=voice_alarm, args=(alarm_sound,))
        alarm.start()

This block of code is used to sound an alarm if a moving object is detected. Here, if the last value in the status_list is greater than or equal to ‘1’ and the last second value is ‘0’, then an alarm is started by using the threading.Thread() function.

cv2.imshow('motion detector', frame)
    key = cv2.waitKey(1)
    if key == ord('q'):
        break

We are then using OpenCV to show our frame window, and specifying a key to close it (here it is ‘q’).

The Complete Code

import cv2
import pyttsx3
import threading

status_list=[None,None]

alarm_sound = pyttsx3.init()
voices = alarm_sound.getProperty('voices')
alarm_sound.setProperty('voice', voices[0].id)
alarm_sound.setProperty('rate', 150)

def voice_alarm(alarm_sound):
    alarm_sound.say("Object Detected")
    alarm_sound.runAndWait()


video=cv2.VideoCapture(0)
initial_frame = None

while True:
    check, frame = video.read()
    frame = cv2.flip(frame,1)
    status=0

    gray_frame=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
    gray_frame=cv2.GaussianBlur(gray_frame,(25,25),0)

    blur_frame = cv2.blur(gray_frame, (5,5))
    
    if initial_frame is None:
        initial_frame = blur_frame
        continue

    delta_frame=cv2.absdiff(initial_frame,blur_frame)
    threshold_frame=cv2.threshold(delta_frame,35,255, cv2.THRESH_BINARY)[1]

    (contours,_)=cv2.findContours(threshold_frame,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)


    for c in contours:
        if cv2.contourArea(c) < 5000:
            continue
        status=status + 1
        (x, y, w, h)=cv2.boundingRect(c)
        cv2.rectangle(frame, (x, y), (x+w, y+h), (0,255,0), 1)
    status_list.append(status)

    if status_list[-1]>= 1 and status_list[-2]==0:
        alarm = threading.Thread(target=voice_alarm, args=(alarm_sound,))
        alarm.start()

    cv2.imshow('motion detector', frame)
    key = cv2.waitKey(1)
    if key == ord('q'):
        break

alarm_sound.stop()
video.release()
cv2.destroyAllWindows()

I hope that this tutorial helped you in understanding the code completely. Thank you.

Leave a Reply

Your email address will not be published. Required fields are marked *