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:
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:
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:
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.
3.16.48.181