车辆计数系统
主要内容:
1、目标检测:背景差分法
2、目标跟踪:DeepSort跟踪算法
3、计数器:多线程定时计数
1车流量计数系统设计
为了能够实时准确地对交通路口地车流量进行统计,在本论文中,首先,我们采用背景差分法对进入交通路口摄像头中的车辆进行检测,由于环境光等干扰因素的影响,会导致不同目标重叠在一起,这将大大降低本系统的检测效果,因此,我们需要对每帧图像进行形态学预处理,消除干扰;其次,使用Deepsort跟踪算法对检测出来的车辆进行跟踪,为了避免目标被遮挡后ID跳变引起的计数不准确的问题,我们采用卡尔曼滤波算法通过当前时刻车辆的运动方向、运动速度等数据预测出车辆下一帧或下几帧可能出现的区域,然后通过提取目标特征并与消失前的特征进行余弦距离度量,将满足阈值的目标恢复其消失前的ID。最后,我们通过计算单位时间内增加的ID数来统计交通路口地车流量。因此,车流量计数系统设计主要分为车辆检测模块、车辆跟踪计数模块
1.1车辆检测模块
对于车辆检测模块,主要由背景建模、差分计算、形态学处理以及框出目标组成。具体流程如下:
第一步:使用KNN背景建模对前20帧图像进行背景建模。通过调用Python-opencv中的createBackgroundSubtractorKNN函数构建背景模型,便于后面的前景提取,具体程序如下:
def build_subtractor(self, history):
bs = cv2.createBackgroundSubtractorKNN(detectShadows=False) # 背景减除器,设置阴影检测
bs.setHistory(history)
return bs
def train(self, frame): # 背景建模
if self.count == self.history:
return True
else:
fg_mask = self.bs.apply(frame) # 获取 foreground mask
self.count += 1
return False
第二步,通过当前帧与背景模型做减法,提取当前帧中的运动目标,如图1.1;
第三步,对第二步中提取的运动目标进行形态学处理,并提取出运动目标位置,同时,使用标记框标记运动目标,实验效果如图1.2所示。
def detect(self, frame): # 检测
fg_mask = self.bs.apply(frame) # 获取 foreground mask
# 对原始帧进行膨胀去噪
th = cv2.threshold(fg_mask.copy(), 244, 255, cv2.THRESH_BINARY)[1]
th = cv2.erode(th, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (1, 1)), iterations=2)
dilated = cv2.dilate(th, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (2, 2)), iterations=2)
# 获取所有检测框
image, contours, hier = cv2.findContours(fg_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
boxes = []
cv2.imshow("fg_mask", fg_mask)
cv2.imshow("dilated", dilated)
for c in contours:
# 获取矩形框边界坐标
x, y, w, h = cv2.boundingRect(c)
if y < self.detection_area[1] or x < self.detection_area[0] or y > self.detection_area[3]:continue # 排除计数区域之外的目标干扰
# 计算矩形框的面积
area = cv2.contourArea(c)
if 500 < area:
boxes.append([x, y, w, h])
return boxes
1.2 车辆跟踪计数模块
1.2.1轨迹处理与状态估计
(1)状态估计: 使用一个8维空间去刻画轨迹在某时刻的状态,分别表示bounding box中心的位置、纵横比、高度、以及在图像坐标中对应的速度信息。然后使用一个卡尔曼滤波器预测更新轨迹,该卡尔曼滤波器采用匀速模型和线性观测模型。其观测变量为
(2)轨迹处理:这个主要说轨迹什么时候终止、什么时候产生新的轨迹。首先对于每条轨迹都有一个阈值a