在本文中,将探讨如何利用背景减除和轮廓检测技术来实现对车辆的运动检测。这项技术可以应用于实时监控视频流中车辆的活动。将通过一个视频文件来演示如何检测车辆。
运动检测技术在多个领域都有广泛的应用,包括交通监控、安全系统以及自动门控制系统。例如,在交通监控中,运动检测可以帮助控制和监控交通流量;在安全系统中,它可以检测到不受欢迎的人类活动;而在自动门控制系统中,如果摄像头检测到门外有人,并且允许该人进入,门就可以自动打开。
在开始构建运动检测应用之前,需要导入所有必要的库。以下是需要用到的一些Python库:
import cv2
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
背景减除是检测和提取图像或视频中对象的最有效和最简单的方法之一。假设有一张带有汽车的高速公路图片(即前景图像),而另一张没有汽车的高速公路图片可以作为背景图像。通过这种方法,可以轻松地使用分割技术将背景图像从前景图像中分割出来(区分汽车),然后使用掩码提取汽车。
但是,为什么还需要背景减除技术呢?当没有清晰的背景图像时,这种技术就显得尤为重要。实际上,要拍摄一张带有移动汽车的高速公路的清晰图片是非常困难的!在这种情况下,背景减除技术可以检测实时动态,而不仅仅是在图像中。这种算法最重要的特点是它更快,适应性更好,比上述传统技术更有效。
现在,将使用背景减除技术来构建车辆检测应用。以下是构建过程的代码和解释。
video = cv2.VideoCapture('media/videos/carsvid.wmv')
kernel = None
backgroundObject = cv2.createBackgroundSubtractorMOG2(detectShadows = True)
while True:
ret, frame = video.read()
if not ret:
break
foreground_mask = backgroundObject.apply(frame)
_, foreground_mask = cv2.threshold(foreground_mask, 250, 255, cv2.THRESH_BINARY)
foreground_mask = cv2.erode(foreground_mask, kernel, iterations = 1)
foreground_mask = cv2.dilate(foreground_mask, kernel, iterations = 2)
contours, _ = cv2.findContours(foreground_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
frameCopy = frame.copy()
for cnt in contours:
if cv2.contourArea(cnt) > 400:
x, y, width, height = cv2.boundingRect(cnt)
cv2.rectangle(frameCopy, (x , y), (x + width, y + height),(0, 0, 255), 2)
cv2.putText(frameCopy, 'Car Detected', (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.3, (0,255,0), 1, cv2.LINE_AA)
foregroundPart = cv2.bitwise_and(frame, frame, mask=foreground_mask)
stacked_frame = np.hstack((frame, foregroundPart, frameCopy))
cv2.imshow('Original Frame, Extracted Foreground and Detected Cars', cv2.resize(stacked_frame, None, fx=0.5, fy=0.5))
k = cv2.waitKey(1) & 0xff
if k == ord('q'):
break
video.release()
cv2.destroyAllWindows()