YOLOv8 测试记录

前言

  YOLOv8 GitHub 地址:https://github.com/ultralytics/ultralytics
  官方文档:https://docs.ultralytics.com/

1. 单路视频目标跟踪

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")

1.1

results = model.track(srcs[0], classes=0, show=True)

问题:

(1)内存泄漏
  视频跑到一半死机了,监测了下使用内存确实不断增长,并且检测和跟踪都会发生内存泄漏(无论是否做可视化)。

1.2 stream

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}'

1.3 逐帧跟踪

  实际的使用环境并不能直接用视频,而是实时的帧,先对单路视频进行测试:

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都在不断递增

2. 多路视频目标跟踪

2.1

  输入可以是多个图像,但不能是多个视频,会直接报错。

inputs = [img, img]
results = model(inputs, stream=True)

results = model.track(srcs, classes=0, stream=True)

2.2 多模型stream

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)跟踪异常
  当画面中出现新的目标时,不会跟踪新的目标。

3. TODO

  很不顺利,内置的跟踪目前是没法用了,整个v8库貌似还在不断更新,官方实现的精度和速度都很不错难以割舍,解决后再更新。

  1. v8做检测,自己做跟踪(已解决)
  2. 看v8源码,解决它的BUG

3.1 BoT-SORT

  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 分别跟踪即可

你可能感兴趣的:(YOLO,python,opencv)