YOLOv8 GitHub 地址:https://github.com/ultralytics/ultralytics
官方文档:https://docs.ultralytics.com/
import cv2
from ultralytics import YOLO
srcs = [
'../calibration/data/nike0110/3/left_side_1.mp4',
'../calibration/data/nike0110/3/left_side_2.mp4',
]
model = YOLO("../Yolov8/yolov8m.pt")
results = model.track(srcs[0], classes=0, show=True)
问题:
(1)内存泄漏
视频跑到一半死机了,监测了下使用内存确实不断增长,并且检测和跟踪都会发生内存泄漏(无论是否做可视化)。
results = model.track(srcs[0], classes=0, stream=True)
cv2.namedWindow('test', cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
for result in results:
res_plotted = result.plot()
cv2.imshow('test', res_plotted)
key = cv2.waitKey(1)
if key == ord('q'):
break
cv2.destroyAllWindows()
问题:
(1)可视化
发现与 1.1 方法的可视化不同,不显示跟踪 ID。查看两种可视化的源码:
1.1 ultralytics/yolo/v8/detect/predict.py line73
name = ('' if id is None else f'id:{id} ') + self.model.names[c]
label = None if self.args.hide_labels else (name if self.args.hide_conf else f'{name} {conf:.2f}')
1.2 ultralytics/yolo/engine/results.py line134
label = (f'{names[c]}' if names else f'{c}') + (f'{conf:.2f}' if show_conf else '')
而获取到的 result
中有 id
属性,简单修改一下源码可以解决:
name = f'id:{int(d.id.item())} {names[c]}' if d.id is not None else names[c]
label = f'{name} {conf:.2f}'
实际的使用环境并不能直接用视频,而是实时的帧,先对单路视频进行测试:
class CVData:
def __init__(self, sources):
self.sources = sources
self.caps = [cv2.VideoCapture(path) for path in sources]
n = len(sources)
self.imgs = [None] * n
def __iter__(self):
return self
def __next__(self):
for i, cap in enumerate(self.caps):
ret, img = cap.read()
if ret:
self.imgs[i] = img
else:
for c in self.caps:
c.release()
raise StopIteration
return self.imgs
srcs = [
'../calibration/data/nike0110/3/left_side_1.mp4',
'../calibration/data/nike0110/3/left_side_2.mp4',
]
dataset = CVData(srcs)
model = YOLO("../Yolov8/yolov8m.pt")
cv2.namedWindow('test', cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
for data in dataset:
# 此处 stream 不受影响, generator 和 list 结果一样
results = model.track(source=data[0], classes=0)
res_plotted = results[0].plot()
cv2.imshow('test', res_plotted)
key = cv2.waitKey(0)
if key == ord('q'):
break
cv2.destroyAllWindows()
问题:
(1)跟踪失灵
所有的ID都在不断递增
输入可以是多个图像,但不能是多个视频,会直接报错。
inputs = [img, img]
results = model(inputs, stream=True)
results = model.track(srcs, classes=0, stream=True)
model1 = YOLO("../Yolov8/yolov8m.pt")
model2 = YOLO("../Yolov8/yolov8m.pt")
cv2.namedWindow('test1', cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
cv2.namedWindow('test2', cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
results1 = model1.track(srcs[0], classes=0, stream=True)
results2 = model2.track(srcs[1], classes=0, stream=True)
for result1, result2 in zip(results1, results2):
res_plotted1 = result1.plot()
res_plotted2 = result2.plot()
cv2.imshow('test1', res_plotted1)
cv2.imshow('test2', res_plotted2)
key = cv2.waitKey(1)
if key == ord('q'):
break
cv2.destroyAllWindows()
问题:
(1)需要多个模型
当只用 model1
时会像逐帧检测一样 ID 不断递增。
(2)跟踪异常
当画面中出现新的目标时,不会跟踪新的目标。
很不顺利,内置的跟踪目前是没法用了,整个v8库貌似还在不断更新,官方实现的精度和速度都很不错难以割舍,解决后再更新。
BoT-SORT GitHub 地址:https://github.com/NirAharon/BoT-SORT
根据给出的示例 mc_demo_yolov7.py
结合 YOLOv8 做跟踪并不复杂,主要就两句:
# Create tracker
tracker = BoTSORT(opt, frame_rate=30.0)
# 输入目标检测结果和原图
online_targets = tracker.update(detections, im0)
多路视频做跟踪声明多个 tracker
分别跟踪即可