Motion detection and tracking

We will now build a sophisticated motion detection and tracking system with a very simple logic of finding the difference between subsequent frames from a video feed, like a webcam stream, and plotting contours around the area where the difference is detected.

Let's import the required libraries and initialize the webcam:

import cv2
import numpy as np

cap = cv2.VideoCapture(0)

We will need a kernel for the dilation operation, which we will create in advance, rather than creating it every time in the loop:

k=np.ones((3,3),np.uint8)

The following code will capture and store subsequent frames:

t0 = cap.read()[1]
t1 = cap.read()[1]

Now, we will initiate the while loop and calculate the difference between both frames, and then convert the output to grayscale for further processing:

while(True):
    
    d=cv2.absdiff(t1,t0)
    
    grey = cv2.cvtColor(d, cv2.COLOR_BGR2GRAY)

The output will be as follows, showing the difference of pixels between the frames:

Motion detection and tracking

This image may contain some noise, so we will blur it first:

    blur = cv2.GaussianBlur(grey,(3,3),0)

We use the binary threshold to convert this noise-removed output into a binary image with the following code:

    ret, th = cv2.threshold( blur, 15, 255, cv2.THRESH_BINARY )

The final operation is to dilate the image so that it is easier for us to find the boundary clearly:

    dilated=cv2.dilate(th,k,iterations=2)

The output of the preceding step is the following:

Motion detection and tracking

Then, we will find and draw the contours for the preceding image with the following code:

    contours, hierarchy = cv2.findContours(dilated,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

    t2=t0
    cv2.drawContours(t2, contours, -1, (0,255,0), 2 )

    cv2.imshow('Output', t2 )

Finally, we will assign the latest frame to the older frame and capture the next frame with a webcam:

    t0=t1
    t1=cap.read()[1]

We will terminate the loop once we detect the Esc keypress, as usual:

    if cv2.waitKey(5) == 27 :
        break

Once the loop is terminated, we will release the camera and destroy the display window:

cap.release()
cv2.destroyAllWindows()

This will draw the contour roughly around the area where the movement is detected, as seen in the following image:

Motion detection and tracking

This code works very well for slow movements. You can make the output more interesting by drawing contours with different colors. Also, you can find out the centroid of the contours and draw crosshairs or circles corresponding to the centroids.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.48.181