点击上方“小白学视觉”,选择加"星标"或“置顶”
重磅干货,第一时间送达
介绍
本文,我们将使用欧几里德距离跟踪和轮廓的概念在 Python 中使用 OpenCV 构建车辆计数器系统。
对象追踪
对象跟踪是在视频中定位移动对象的过程。在 OpenCV 中有多种技术可以执行对象跟踪。可以针对 2 种情况执行对象跟踪:
跟踪单个对象
跟踪多个对象
在这里,我们将执行多对象跟踪方法,因为我们在一个时间范围内有多辆车。
流行的追踪算法
DEEP SORT:它是最广泛使用和非常有效的目标跟踪算法之一,它适用于 YOLO 目标检测,使用卡尔曼滤波器进行跟踪。
质心跟踪算法:质心跟踪算法是一种易于理解且非常有效的算法。这是一个多步骤的过程。
步骤 1:获取检测到的对象的边界框坐标并使用边界框的坐标计算质心。
步骤 2:对于每个后续帧,它使用边界框坐标计算质心,并为这些边界框分配一个 id,并计算每个可能的质心之间的欧几里德距离。
步骤 3:我们的假设是给定对象可能会在后续帧中移动,并且它们质心之间的欧几里德距离将是与其他对象相比的最小距离。
步骤 4:将相同的 ID 分配给后续帧之间的最小移动质心。
为了检测任何运动物体,我们可以用 frame(t) 减去 frame(t+1)。
对象跟踪的应用
因为计算机不断增长的计算能力,对象跟踪变得越来越先进。对象跟踪有一些主要的用例。
交通跟踪和避免碰撞。
人群追踪
无人在家时进行宠物追踪
导弹跟踪
空气画笔
实现欧几里得距离跟踪器
本文使用的所有代码的源文件和测试视频都可以通过这个链接下载:
https://github.com/Abhishekjl/OPENCV-
上面讨论的所有步骤都可以使用一些数学计算来执行
我们已经建立了一个名为EuclideanDistTracker
对象跟踪的类。
import math
class EuclideanDistTracker:
def __init__(self):
# Storing the positions of center of the objects
self.center_points = {}
# Count of ID of boundng boxes
# each time new object will be captured the id will be increassed by 1
self.id_count = 0
def update(self, objects_rect):
objects_bbs_ids = []
# Calculating the center of objects
for rect in objects_rect:
x, y, w, h = rect
center_x = (x + x + w) // 2
center_y = (y + y + h) // 2
# Find if object is already detected or not
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
# Assign the ID to the detected object
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
# Cleaning the dictionary ids that are not used anymore
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
# Updating the dictionary with IDs that is not used
self.center_points = new_center_points.copy()
return objects_bbs_ids
你可以创建一个名为tracker.py
并粘贴跟踪器代码的文件,也可以使用此链接(https://github.com/Abhishekjl/OPENCV-)直接下载跟踪器文件。
update
→更新方法需要一个包含所有边界框坐标的数组。tracker 返回一个包含 [x,y,w,h, object_id] 的数组。这里 x,y,w,h 是边界框的坐标,object_id 是与该边界框关联的 id。
在准备好跟踪器文件后,我们需要实现我们的目标检测器,稍后我们将我们的跟踪器与目标检测器绑定。
加载库和视频
从我们已经创建的 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():
# ret, frame = cap.read()
diff = cv2.absdiff(frame1, frame2)
# this method is used to find the difference bw two frames
gray = cv2.cvtColor(diff, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (5,5), 0 )
# here i would add the region of interest to count the single lane cars
height, width = blur.shape
print(height, width)
# thresh_value = cv2.getTrackbarPos('thresh', 'trackbar')
_, 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 = []
# DRAWING RECTANGLE BOX (Bounding Box)
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()
cv2.absdiff
此方法用于获取两帧之间的绝对差。得到帧差后将差值转换为灰度,然后应用阈值和轮廓检测。
找到的轮廓是所有运动物体的轮廓
为了避免所有的噪音,我们只采用那些尺寸大于 300 的轮廓。
boxes_ids
包含 (x,y,w,h,id)。cv2.putText
用于在框架上写入 Id。cv2.rectange()
用于绘制边界框。
输出:车辆计数器系统
结论
在本文中,我们讨论了对象跟踪的概念和对象跟踪的用例,即车辆计数器。
我们讨论了对象跟踪的一些应用,并讨论了质心跟踪算法中涉及的步骤,并将其用于车辆计数。
基于深度学习的对象跟踪算法(如用于 YOLO 对象检测的 DEEP SORT 算法)在我们的案例中执行得更准确。
好消息!
小白学视觉知识星球
开始面向外开放啦👇👇👇
下载1:OpenCV-Contrib扩展模块中文版教程
在「小白学视觉」公众号后台回复:扩展模块中文教程,即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。
下载2:Python视觉实战项目52讲
在「小白学视觉」公众号后台回复:Python视觉实战项目,即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。
下载3:OpenCV实战项目20讲
在「小白学视觉」公众号后台回复:OpenCV实战项目20讲,即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。
交流群
欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~