OpenCV detect movement in python
One way to detect movement is to keep a running average of your scene using cv2.accumulateWeighted. Then, compare every new frame to the average using cv2.absdiff to get the image that indicates changes in the scene.
I did exactly this in a video processing project of mine. Check out the main loop in file diffavg1.py
where I run the accumulator and perform the diff.
(The research of the project was to achieve realtime video processing utilizing multi-core CPU architecture, so the later versions diffavg2.py
, diffavg3.py
and diffavg4.py
are progressively higher performance implementations, but the underlying accumulate-diff algorithm is the same.)
Differential Images are the result of the subtraction of two images
So differential image shows the difference between two images. With those images you can make movement visible.
In following script we use a differential image calculated from three consecutive images , and . The advantage of this is that the uninteresting background is removed from the result.
OpenCV offers the possibility to subtract two images from each other using absdiff(). Also logical operations on two images is already implemented. We use the method bitwise_and() to achieve the final differential image. In python it looks like this:
def diffImg(t0, t1, t2):
d1 = cv2.absdiff(t2, t1)
d2 = cv2.absdiff(t1, t0)
return cv2.bitwise_and(d1, d2)
The last thing we have to do is bringing the differential image function into our previous script. Before the loop starts we read the first three images t_minus, t and t_plus and convert them into greyscale images as we dont need color information. With those images it is possible to start calculating differential images. After showing the differential image, we just have to get rid of the oldest image and read the next one. The final script looks like this:
import cv2
def diffImg(t0, t1, t2):
d1 = cv2.absdiff(t2, t1)
d2 = cv2.absdiff(t1, t0)
return cv2.bitwise_and(d1, d2)
cam = cv2.VideoCapture(0)
winName = "Movement Indicator"
cv2.namedWindow(winName, cv2.CV_WINDOW_AUTOSIZE)
# Read three images first:
t_minus = cv2.cvtColor(cam.read()[1], cv2.COLOR_RGB2GRAY)
t = cv2.cvtColor(cam.read()[1], cv2.COLOR_RGB2GRAY)
t_plus = cv2.cvtColor(cam.read()[1], cv2.COLOR_RGB2GRAY)
while True:
cv2.imshow( winName, diffImg(t_minus, t, t_plus) )
# Read next image
t_minus = t
t = t_plus
t_plus = cv2.cvtColor(cam.read()[1], cv2.COLOR_RGB2GRAY)
key = cv2.waitKey(10)
if key == 27:
cv2.destroyWindow(winName)
break
print "Goodbye"
Here you will find more elaborative answer, for what you are looking for.