文章目录

前言更新

一、目标跟踪算法选择二、直接上手1.找资源2.测试代码1(1)检测效果(2)评价

3.测试代码2(1)检测效果(2)评价(3)我的改进

4.测试代码3(1)检测效果(2)评价(3)我的改进

三、总结附录(本文gif在线工具)

前言

近期实习项目可能需要目标跟踪,所以学习了一下目标跟踪算法,并根据了解到的算法,在github上寻找项目直接上手验证。

更新

1、如果出现这个问题

return _VF.meshgrid(tensors, **kwargs, indexing = 'ij') # type: ignore[attr-defined]

TypeError: meshgrid() got multiple values for keyword argument 'indexing'

删除indexing = 'ij即可,即变为。return _VF.meshgrid(tensors, **kwargs) 2、嵌入自己任意版本的yolo中。请查看最新的方法。 https://blog.csdn.net/qq_45874142/article/details/132586026?spm=1001.2014.3001.5501

一、目标跟踪算法选择

看了一些综述,发现每个人的分类都不太一样,而且分的很详细,就连传统机器学习里面的方法都提出来了。看的甚是头大,我看了一天,晚上头疼死了。如果直接奔着项目来上手,那就简单多了,目前多用的是深度学习yolov5,因此,找了深度学习方向的目标跟踪,同样很多算法,但大家常用的,资源最多的,还是用Deepsort算法。原理自己去找吧,涉及到卡尔曼和匈牙利算法。 这有几个链接可以参考(我后面可能深入的话也需要细看,就做个笔记记录一下): Deep sort算法代码解读(这个最详细,但很不友好) Deepsort-Yolov3目标跟踪相关学习 YOLOv8 + DeepSORT | YOLO与DeepSORT跟踪的难分难舍,直接用吧(附源码)

二、直接上手

1.找资源

这个目标跟踪代码有很多,但都是参考这个大牛的,大牛主页:https://github.com/mikel-brostrom

但这个我下载后,不会用。我小白,抱歉了。这个貌似是已经更新过了。看很多人参考的代码,并不是这个更新的,而是之前的版本,之前的版本貌似只有gitcode上有。 mirrors / mikel-brostrom / Yolov5_DeepSort_Pytorch

还有很多资源,大多都是要么需要私信、一键三连,甚至有收费29.9的,恶心心,可怕怕。如果加上轨迹跟踪,基本网上没有。所以我后面直接在github上找了。大概找了一些,并测试可用,然后就分享给大家。

2.测试代码1

这个资源是github上的,https://github.com/HowieMa/DeepSORT_YOLOv5_Pytorch

(1)检测效果

(2)评价

有显示检测帧率,标签只显示了ID,没有类别和概率,总体还不错。也没有轨迹显示。

3.测试代码2

资源地址:https://github.com/Sharpiless/yolov5-deepsort/

(1)检测效果

(2)评价

帧率打印输出是摄像头的帧率,没有推理的帧率。 增加了标签的类别显示。 把检测和其他模块都进行的打包,自己写一个demo进行掉包检测,上手简单,但不利于再次修改调用位置挺多。大佬能加上类别,也是挺厉害的。

(3)我的改进

我增加了平均帧率显示,把每帧的fps放进列表中,每20个计算一次平均值,每20次更新一次。 在detector里面的检测推理部分修改的。

def detect(self, im):

im0, img = self.preprocess(im)

t0 = time.time() # 记录开始时间

pred = self.m(img, augment=False)[0]

pred = pred.float()

pred = non_max_suppression(pred, self.threshold, 0.4)

pred_boxes = []

for det in pred:

if det is not None and len(det):

det[:, :4] = scale_coords(

img.shape[2:], det[:, :4], im0.shape).round()

for *x, conf, cls_id in det:

lbl = self.names[int(cls_id)]

if not lbl in ['person', 'car', 'truck']:

continue

x1, y1 = int(x[0]), int(x[1])

x2, y2 = int(x[2]), int(x[3])

pred_boxes.append(

(x1, y1, x2, y2, lbl, conf))

t1 = time.time() # 记录结束时间

fps = 1 / (t1 - t0) # 计算帧率

self.fps_list.append(fps)

if len(self.fps_list) > 20: # 保留最近的20个帧率数据

self.fps_list.pop(0)

self.fps_average = sum(self.fps_list) / len(self.fps_list) # 计算平均帧率

cv2.putText(im, f'Avg FPS: {self.fps_average:.2f}', (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255),2)

return im, pred_boxes

4.测试代码3

因为想要轨迹,所以我就一直在找有轨迹的代码,基本没有,好不容易找到一个 Deepsort跟踪算法画目标运动轨迹 我也做了相关的改进,下面的效果是我改进之后的效果。你可以自己改进,也可以直接用我的。注意这个代码是用的原来的yolov5,版本不知道,猜测是5.0以下。后续将替换为我们版本的yolov5,我用的是6.1版本。 我的仓库代码直达:https://github.com/zzzbut/Yolov5_DeepSort_Track

(1)检测效果

(2)评价

作者增加了轨迹,根据目标框计算的。 但是轨迹一直会留在图上,就算目标走了也会留着。颜色分配也不一致,是乱的。

(3)我的改进

根据ID分配颜色,颜色是一致的了。 轨迹限制最近的一段。 轨迹显示与目标框搭配,目标框在的时候,才显示轨迹,没有目标id,直接跳过显示,就不绘制。核心代码就是下面的。如果有需要的,我可近期挂github上,现在我还不会挂,近期应该要学习一下。 但我还没加上类别和置信度。这个我其实不太会加。有大佬可以一起交流一下。

# Pass detections to deepsort

outputs = deepsort.update(xywhs, confss, im0)

# outputs = [x1, y1, x2, y2, track_id]

if len(outputs) > 0:

bbox_xyxy = outputs[:, :4] # 提取前四列 坐标

identities = outputs[:, -1] # 提取最后一列 ID

draw_boxes(im0, bbox_xyxy, identities)

box_xywh = xyxy2tlwh(bbox_xyxy)

# xyxy2tlwh是坐标格式转换,从x1, y1, x2, y2转为top left x ,top left y, w, h 具体函数看文章最后

for j in range(len(box_xywh)):

x_center = box_xywh[j][0] + box_xywh[j][2] / 2 # 求框的中心x坐标

y_center = box_xywh[j][1] + box_xywh[j][3] / 2 # 求框的中心y坐标

id = outputs[j][-1]

center = [x_center, y_center]

dict_box.setdefault(id, []).append(center) # 这个字典需要提前定义 dict_box = dict()

# 以下为画轨迹,原理就是将前后帧同ID的跟踪框中心坐标连接起来

if frame_idx > 2: # 这里可以调整判断条件

max_trajectory_length = 50 # 设置轨迹的最大长度

temp_dict_box = dict_box.copy() # 创建字典的副本

for key, value in temp_dict_box.items():

if key in identities: # 判断目标是否存在

if len(value) > max_trajectory_length: # 限制轨迹长度

value = value[-max_trajectory_length:] # 截断保留最近的一部分轨迹

for a in range(len(value) - 1):

color = compute_color_for_labels(key) # 使用固定颜色

index_start = a

index_end = index_start + 1

cv2.line(im0, tuple(map(int, value[index_start])),

tuple(map(int, value[index_end])),

color, thickness=5, lineType=8)

else:

continue

三、总结

测试了三个目标跟踪的代码,总体效果不错,也做了适当的改进,比如加入平均帧率显示,加入轨迹线的一段显示和目标框消失即不显示。

附录(本文gif在线工具)

视频转gif工具:https://www.img2go.com/zh/convert-video-to-gif gif压缩工具:https://gifcompressor.com/zh/

精彩文章

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。