基于OpenCV的车辆计数系统

对象跟踪

对象跟踪是指跟踪或保持移动对象的身份,无论其移动到哪里。在OpenCV中执行对象跟踪有多种技术。对象跟踪可以用于两种情况:单对象跟踪和多对象跟踪。在这里,将执行多对象跟踪方法,因为在单个时间帧中有多个车辆。

DEEP SORT:这是最广泛使用且非常有效的对象跟踪算法之一,它基于YOLO对象检测工作。它使用卡尔曼滤波器进行跟踪。

质心跟踪算法:质心跟踪算法易于理解且非常有效。这是一个多步骤过程。

获取检测到的对象的边界框坐标,并使用边界框的坐标计算质心。

对于每个后续帧,使用边界框坐标计算质心,并为这些边界框分配ID,并计算每个质心之间可能的欧几里得距离

假设是,给定的对象可能会在后续帧中移动,它们质心之间的欧几里得距离将是与其他对象相比的最小距离。

在后续帧之间最小移动的质心分配相同的ID。

对象跟踪的应用

随着计算能力的增长,对象跟踪正在变得先进。对象跟踪的一些主要用例包括交通跟踪和避免碰撞、人群跟踪、家中无人时的宠物跟踪、导弹跟踪和空中画布笔。

实现欧几里得距离跟踪器

本文中使用的所有代码源文件和测试视频可以通过此链接下载。以上讨论的所有步骤都可以使用一些数学计算来执行。构建了一个名为EuclideanDistTracker的类来进行对象跟踪。

import math class EuclideanDistTracker: def __init__(self): # 存储对象中心的位置 self.center_points = {} # 边界框ID计数 # 每次捕获新对象时,ID将增加1 self.id_count = 0 def update(self, objects_rect): objects_bbs_ids = [] # 计算对象的中心 for rect in objects_rect: x, y, w, h = rect center_x = (x + x + w) // 2 center_y = (y + y + h) // 2 # 查找是否已经检测到对象 same_object_detected = False for id, pt in self.center_points.items(): dist = math.hypot(center_x - pt[0], center_y - pt[1]) if dist < 25: self.center_points[id] = (center_x, center_y) print(self.center_points) objects_bbs_ids.append([x, y, w, h, id]) same_object_detected = True break # 为检测到的对象分配ID if same_object_detected is False: self.center_points[self.id_count] = (center_x, center_y) objects_bbs_ids.append([x, y, w, h, self.id_count]) self.id_count += 1 # 清理不再使用的字典ID new_center_points = {} for obj_bb_id in objects_bbs_ids: var,var,var,var, object_id = obj_bb_id center = self.center_points[object_id] new_center_points[object_id] = center # 更新不再使用的ID的字典 self.center_points = new_center_points.copy() return objects_bbs_ids

可以创建一个名为tracker.py的文件并粘贴跟踪器的代码,或者直接使用此链接下载跟踪器文件。

加载库和视频

从已经创建的tracker.py文件中导入EuclideanDistTracker类。

import cv2 import numpy as np from tracker import EuclideanDistTracker tracker = EuclideanDistTracker() cap = cv2.VideoCapture('highway.mp4') ret, frame1 = cap.read() ret, frame2 = cap.read() cap.read()

它返回帧和布尔值,需要捕获帧。

OpenCV中获取视频帧

while cap.isOpened(): diff = cv2.absdiff(frame1, frame2) gray = cv2.cvtColor(diff, cv2.COLOR_BGR2GRAY) blur = cv2.GaussianBlur(gray, (5,5), 0 ) height, width = blur.shape print(height, width) _, threshold = cv2.threshold(blur, 23, 255, cv2.THRESH_BINARY) dilated = cv2.dilate(threshold, (1,1), iterations=1) contours, _ = cv2.findContours(dilated, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) detections = [] for contour in contours: (x,y,w,h) = cv2.boundingRect(contour) if cv2.contourArea(contour) <300: continue detections.append([x,y,w,h]) boxes_ids = tracker.update(detections) for box_id in boxes_ids: x,y,w,h,id = box_id cv2.putText(frame1, str(id),(x,y-15), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0,0,255), 2) cv2.rectangle(frame1, (x,y),(x+w, y+h), (0,255,0), 2) cv2.imshow('frame',frame1) frame1 = frame2 ret, frame2 = cap.read() key = cv2.waitKey(30) if key == ord('q'): break cv2.destroyAllWindows()
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485