前言:
我说的顺序布置可能有些地方不对,因为安装已经是前几天前的事情,这都是凭借我的记忆敲下去的,但我敢保证,安装过程中出的错误一般都可以在这篇文章中找到,你将踩的坑我基本上已经都踩过了,整个安装过程折腾了3个多小时,中间不是在报错就是在报错的路上,网上相似案例几乎没有,也没有相关博客来给一个保姆级别的教程,所以想到这我就开始写这篇文章了,文笔不是很好,还是希望对你有帮助!
所需工具
MiniConda Pycharm(vscode也行) python3.8
正文:
Step1 建立虚拟环境
conda create -n bytetrack python=3.8
这个python版本最好选择3.8,不要选择3.9!!!,这个后面会讲
激活
conda activate bytetrack
克隆
git clone https://github.com/ifzhang/ByteTrack.git
进入目录
cd ByteTrack
在安装requirements.txt依赖之前,需要先下载几个包,否则后续配置会报错
pip install cython cython-bbox cmake
提前说了,后续安装还会报错protobuf版本太高,针对这个报错,应该降低protobuf版本
pip uninstall protobuf
pip install protobuf==1.20.3
安装依赖,这一步比较漫长
pip install -r requirements.txt
安装onnx,会报错 onnxruntime 的问题,这个需要我们手动从官网安装 onnxruntime对应版本
查询requirements.txt,可知所需onnx-runtime版本1.8.0,从中pypi选择适合你系统的版本。
这里还是要插一句,就是python3.9版本运行到这一步就会报错git仓库错误和找不到cmake模块的问题(即使你已经安装了cmake),这个可以认为是python3.9与某些模块不兼容,3.8,3.7是没问题的。
onnx-runtime PyPI 1.8.0https://pypi.org/project/onnxruntime/1.8.0/#files
如果你是x86 win系统,python3.8选择这个就是了 ,下载后把包放在项目目录,安装到虚拟环境中即可。
pip install onnxruntime-1.20.1-cp312-cp312-win_amd64.whl
接下来,我们要运行setup.py,把yolox包解析出来
在执行setup.py之前,还请你进去setup.py
如下图所示,在对应位置加入
encoding="utf-8"
python setup.py develop
进行到这一步,离成功也不远了
这时你的项目目录大概长这样
已经部署好了吗?
可以告诉你还没有!!!
这是因为你的numpy虽然安装了,但安装的版本过高,而高版本的np.float,np.object已经弃用。
这里你可能会说把numpy卸载了,下载一个低版本的不就行了,我也试过,但这里又有一个问题,就是torch包却必须用到高版本的numpy!
那这该怎么办呢!
只能修改byteTrack源代码了
这里小编当时安装时未截图,就不能结合图片展示如何修改,只能告诉你个大概,我说实话,只需把4个地方的np.float,np.object的np.删去即可。
具体是在2个还是在3个python文件里,这个文件怎么找呢,你直接运行一遍setup.py,它会报错,在报错信息中就会提示np.的前缀问题,你按住ctrl,单击出问题的python文件链接,按住ctrl+F,去搜寻np.float,np.object删去前缀即可,主要其它的np.前缀的变量不需要删去!!
执行到这里,运行setup.py,就能跑成功了
来看看效果
pip install opencv,ultralytics
模型文件选择你自己的路径
如果没有angparse包,可以pip一个
import cv2
import numpy as np
import torch
from ultralytics import YOLO
import tkinter as tk
from tkinter import ttk
from yolox.tracker.byte_tracker import BYTETracker # ByteTrack 跟踪器
import argparse
model = YOLO("yolo11n.pt")
args = argparse.Namespace(
track_thresh=0.5,
track_buffer=30,
match_thresh=0.8,
mot20=False
)
tracker = BYTETracker(args, frame_rate=30)
def get_available_cameras(max_cameras=10):
"""获取可用摄像头列表"""
available_cameras = []
for i in range(max_cameras):
cap = cv2.VideoCapture(i)
if cap.isOpened():
available_cameras.append(f"Camera {i}")
cap.release()
return available_cameras
def start_detection(camera_index):
"""启动实时检测和跟踪"""
camera_index = int(camera_index.split()[-1])
cap = cv2.VideoCapture(camera_index)
if not cap.isOpened():
print(f"无法打开摄像头 {camera_index}")
return
while True:
ret, frame = cap.read()
if not ret:
print("无法读取画面")
break
results = model(frame)
detections = []
cls_list = []
for result in results:
boxes = result.boxes
for box in boxes:
x1, y1, x2, y2 = map(int, box.xyxy[0])
conf = float(box.conf[0])
cls = int(box.cls[0])
detections.append([x1, y1, x2, y2, conf])
cls_list.append(cls)
if detections:
detections = np.array(detections)
else:
detections = np.empty((0, 5))
detections_tensor = torch.from_numpy(detections).float()
tracked_objects = tracker.update(detections_tensor, (frame.shape[0], frame.shape[1]), (frame.shape[0], frame.shape[1]))
for i, obj in enumerate(tracked_objects):
tlbr = obj.tlbr
track_id = obj.track_id
cls = cls_list[i] if i < len(cls_list) else -1
x1, y1, x2, y2 = map(int, tlbr)
label = f"ID: {track_id} {model.names[int(cls)]}"
cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
cv2.putText(frame, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)
# 显示画面
cv2.imshow("YOLO + ByteTrack Real-Time Detection", frame)
# 按下 'q' 键退出
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 释放资源
cap.release()
cv2.destroyAllWindows()
def create_gui():
root = tk.Tk()
root.title("摄像头选择")
cameras = get_available_cameras()
if not cameras:
tk.messagebox.showerror("错误", "未检测到可用摄像头!")
root.destroy()
return
# 创建下拉菜单
selected_camera = tk.StringVar()
selected_camera.set(cameras[0]) # 默认选择第一个摄像头
camera_menu = ttk.Combobox(root, textvariable=selected_camera, values=cameras, state="readonly")
camera_menu.pack(pady=20)
def on_start():
root.destroy() # 关闭 GUI 窗口
start_detection(selected_camera.get())
start_button = tk.Button(root, text="开始检测", command=on_start)
start_button.pack(pady=10)
root.mainloop()
if __name__ == "__main__":
create_gui()
效果:(拍摄于寝室)
这里ID随着镜头晃动表现出良好稳定性,目标跟踪效果良好
完结,撒花!!!