现在的交通系统已经高度依赖视频监控设备获得的实时交通信息,基于视频监控,实现自动检测车辆运动目标,提取车辆目标速度,运动轨迹,车辆特征,车流密度,车牌号码等信息。
长话短说,马路上人来车往,有行人,有骑自行车的,有骑电瓶车的,再者就是我们的汽车,所以对车辆实时测速的第一步肯定是先对马路上跑的分类,分成行人、自行车、电瓶车、汽车,当然这里我们只需要找出汽车,对汽车测速。
我们知道,有了特征才能分类,这里我们主要提取车辆的Harr特征,利用Harr特征首先训练出用于识别车辆的分类器。
初步检测到车辆之后,我们就要考虑,当车辆在我们的视频当中由近驶远时候,车辆由大变小,那么这时,为了能够识别图像中各个位置和各种尺寸大小的车辆,我们需要采用多尺度识别机制。
传统的物体识别机制是一种称为“金字塔式”的图像多尺度变换方法。该方法的识别窗口大小固定,将待识别图像按比例逐层缩小,形成一个“图像金字塔”然后把各个缩放的图像作为分类器的输入,得到最终的识别结果,如图示。
正如我们常看到的,检测到车辆之后,通常会分别给每个车辆一个框,一般用 ( x , y , w , h ) (x,y,w,h) (x,y,w,h)来标识这个识别框,其中(x,y)表示识别窗口左上角相对于图像的坐标,(w,h)表示子窗口的宽和高。
视频测速,是指将安装在道路上方的摄像机拍摄的车辆行驶图像序列,运用图像处理技术进行分析,并通过摄像机的标定建立图像像素坐标与空间中对应点的世界坐标的映射关系,获取车辆在一段时间内的实际位移,从而求出车辆速度。
通过一定的方法获取车辆在一段时间内的像素位移,通过摄像机的标定来建立图像像素坐标与空间中对应点的世界坐标的映射关系,从而根据车辆的像素位移求出车辆的实际位移,进而计算车辆速度。
import cv2
import dlib
import time
import threading
import math
#加载车辆识别文件
#加载车辆识别的分类器
carCascade = cv2.CascadeClassifier('myhaar.xml')
#读取视频文件
video = cv2.VideoCapture('video//cars.mp4')
WIDTH = 720
HEIGHT = 560
carWidht = 1.85
# def carNumber(carNum, cID):
# time.sleep(2)
# carNum[cID] = 'Car ' + str(cID)
def estimateSpeed(location1, location2, mySpeed,fps):
#计算像素距离
d_pixels = math.sqrt(math.pow(location2[0] - location1[0], 2) + math.pow(location2[1] - location1[1], 2))
ppm = location2[2] / carWidht
d_meters = d_pixels / ppm
speed = mySpeed + d_meters * fps
return speed
def trackMultipleObjects():
rectangleColor = (0, 0, 255)
frameCounter = 0
currentCarID = 0
fps = 0
carTracker = {}
carNumbers = {}
carLocation1 = {}
carLocation2 = {}
while True:
start_time = time.time()
#读取帧
rc, image = video.read()
#检查是否到达视频文件的末尾
if type(image) == type(None):
break
#转换帧的大小,以加快处理速度
image = cv2.resize(image, (WIDTH, HEIGHT))
resultImage = image.copy()
frameCounter = frameCounter + 1
carIDtoDelete = []
for carID in carTracker.keys():
trackingQuality = carTracker[carID].update(image)
if trackingQuality < 7:
carIDtoDelete.append(carID)
for carID in carIDtoDelete:
print('Removing carID ' + str(carID) + ' from list of trackers.')
print('Removing carID ' + str(carID) + ' previous location.')
print('Removing carID ' + str(carID) + ' current location.')
carTracker.pop(carID, None)
carLocation1.pop(carID, None)
carLocation2.pop(carID, None)
# frameCounter为10的倍数的时候,执行
if not (frameCounter % 10):
#将图像转换成灰度图像
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
#检测视频中的车辆,并用vector保存车辆的坐标、大小(用矩形表示)
# x,y表示第n帧第i个运动目标外接矩形的中心横坐标和纵坐标位置,该坐标可以大致描述车辆目标所在的位置。
# w,h表示第n帧第i个运动目标外接矩形的宽度和长度,可以描述车辆目标的大小
cars = carCascade.detectMultiScale(gray, 1.1, 13, 0, (24, 24))
#车辆检测
for (_x, _y, _w, _h) in cars:
x = int(_x)
y = int(_y)
w = int(_w)
h = int(_h)
x_bar = x + 0.5 * w
y_bar = y + 0.5 * h
matchCarID = None
for carID in carTracker.keys():
trackedPosition = carTracker[carID].get_position()
t_x = int(trackedPosition.left())
t_y = int(trackedPosition.top())
t_w = int(trackedPosition.width())
t_h = int(trackedPosition.height())
t_x_bar = t_x + 0.5 * t_w
t_y_bar = t_y + 0.5 * t_h
if ((t_x <= x_bar <= (t_x + t_w)) and (t_y <= y_bar <= (t_y + t_h)) and (x <= t_x_bar <= (x + w)) and (y <= t_y_bar <= (y + h))):
matchCarID = carID
if matchCarID is None:
print('Creating new tracker ' + str(currentCarID))
#构造追踪器
tracker = dlib.correlation_tracker()
# 设置追踪器的初始位置
#如果识别出车辆,会以Rect(x,y,w,h)的形式返回车辆的位置,然后我们可以用一个矩形网格标识车辆
tracker.start_track(image, dlib.rectangle(x, y, x + w, y + h))
carTracker[currentCarID] = tracker
# 用于生成追踪器所需要的矩形框[(startX, startY), (endX, endY)]
carLocation1[currentCarID] = [x, y, w, h]
# t = threading.Thread(target = carNum, args = (carNumbers, currentCarID))
# t.start()
currentCarID = currentCarID + 1
for carID in carTracker.keys():
# 获得追踪器的当前位置
trackedPosition = carTracker[carID].get_position()
t_x = int(trackedPosition.left())
t_y = int(trackedPosition.top())
t_w = int(trackedPosition.width())
t_h = int(trackedPosition.height())
cv2.rectangle(resultImage, (t_x, t_y), (t_x + t_w, t_y + t_h), rectangleColor, 2)
# speed estimation
carLocation2[carID] = [t_x, t_y, t_w, t_h]
# if carID in carNumbers.keys():
# cv2.putText(resultImage, carNumbers[carID], (int(t_x + t_w/2), int(t_y)),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)
# else:
# cv2.putText(resultImage, 'Detecting...', (int(t_x + t_w/2), int(t_y)),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)
end_time = time.time()
if not (end_time == start_time):
fps = 1.0/(end_time - start_time)
print(fps)
cv2.putText(resultImage, 'FPS: ' + str(int(fps)), (620, 30),cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2)
for i in carLocation1.keys():
if frameCounter % 10 == 0:
[x1, y1, w1, h1] = carLocation1[i]
[x2, y2, w2, h2] = carLocation2[i]
print ('previous location: ' + str(carLocation1[i]) + ', current location: ' + str(carLocation2[i]))
carLocation1[i] = [x2, y2, w2, h2]
print('new previous location: ' + str(carLocation1[i]))
if [x1, y1, w1, h1] != [x2, y2, w2, h2]:
speed = estimateSpeed([x1, y1, w1, h1], [x2, y2, w2, h2], 100, fps)
print('CarID ' + str(i) + ' speed is ' + str("%.2f" % round(speed, 2)) + ' km/h.\n')
cv2.imshow('result', resultImage)
if cv2.waitKey(33) == 27:
break
cv2.destroyAllWindows()
if __name__ == '__main__':
trackMultipleObjects()