bytetrack漏检补齐

bytetrack漏检补齐

1.人流慢速运动,跟踪效果比较好,偶尔有漏检,跟踪可以自动补齐。

2.快速运动,频繁遮挡,效果可能不好

*如果漏检,倒着跟踪,把丢失的检测框拷贝出来,保留进行跟踪。

有时候效果不是很好

from collections import defaultdict
import cv2
import numpy as np
import torchvision
from ultralytics import YOLO
import pickle
import torch
from torchvision.ops import box_iou
from log import logger
import time
import os
from addict import Dict
from track.byte_tracker import BYTETracker
import mathdef get_color(idx):idx = idx * 5color = ((37 * idx) % 255, (17 * idx) % 255, (29 * idx) % 255)return colorclass YOLO_Class():def __init__(self, model_path, device="cuda:0"):self.model = YOLO(model_path)  # YOLO‑12 检测 + 跟踪self.par_args = Dict({"track_thresh": 0.5, "track_buffer": 30, "match_thresh": 0.9, "min_box_area": 10, "mot20": False})self.tracker = BYTETracker(self.par_args, frame_rate=20)def yolo_byte_track(self,detect_bboxes, frame):title_color = (0, 255, 255)person_sum = 0# print(f"bboxes: {detect_bboxes}")if len(detect_bboxes) > 0:if len(detect_bboxes) > 4:self.par_args.track_buffer = 60self.par_args.match_thresh = 1.6else:self.par_args.track_buffer = 30self.par_args.match_thresh = 0.9online_targets = self.tracker.update(np.array(detect_bboxes), [frame.shape[0], frame.shape[1]],(frame.shape[0], frame.shape[1]), self.par_args)# print("len(det)", len(detect_bboxes), "len track", len(online_targets))for index, t in enumerate(online_targets):tlwh = t.tlwhx1, y1, w, h = tlwhif w > 0 and h > 0:bbbb = t.track_idperson_sum = max(person_sum, bbbb)box_color = get_color(t.track_id)intbox = tuple(map(int, (x1, y1, x1 + w, y1 + h)))cv2.rectangle(frame, intbox[0:2], intbox[2:4], color=box_color, thickness=2)hull = [[x1, y1], [x1 + w, y1], [x1 + w, y1 + h], [x1, y1 + h]]# for index, point in enumerate(track_dict[bbbb]):# dist = cv2.pointPolygonTest(np.array(hull).astype(np.int32), tuple(point), True)#<0 out >0 in# if index==len(track_dict[t.track_id])-4 and t.track_id < 3:#     print('----------------', abs(point[0] - (x1 + w / 2)), abs(point[1]-(y1+h)))# cv2.rectangle(frame, (intbox[2],intbox[1]), (int(intbox[2]+70),int(intbox[1]+80)), color=box_color , thickness=1)cv2.putText(frame, f'{bbbb} {t.score:.2f} ', (intbox[0], intbox[1] - 5), cv2.FONT_HERSHEY_PLAIN,1.8, title_color, thickness=2)return framedef get_bytetrack_bbox(self, video_path, video_id, output_path="", debug:bool=False):debug_dir = f"yolov12/debug/{video_id}" if debug else Noneos.makedirs(debug_dir, exist_ok=True)  # 确保调试目录存在# ----------------- 基本参数 -----------------track_history = defaultdict(list)  # 保存每个 track 的历史中心点cap = cv2.VideoCapture(video_path)if not cap.isOpened():raise RuntimeError(f"无法打开视频: {video_path}")fps = cap.get(cv2.CAP_PROP_FPS) or 30  # 有些文件读不到 FPS,给默认w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))logger.info(f"视频总帧数: {total_frames}, fps: {fps}, 宽: {w}, 高: {h}")frame_id = 0fourcc = cv2.VideoWriter_fourcc(*"mp4v")out = cv2.VideoWriter(output_path, fourcc, fps, (w, h))if not out.isOpened():raise RuntimeError("VideoWriter 初始化失败,请检查编码器 fourcc 或路径。")last_box=[]while cap.isOpened():ok, frame = cap.read()if not ok:break# YOLO11 跟踪(persist=True 保持 track ID)t0 = time.time()results = detect_image_yolo(self.model,frame)pic_h,pic_w = frame.shape[:2]  # if frame_id%4==3:#     results = np.delete(results, 1, axis=0)pad_count = len(last_box) - len(results)if pad_count>0 and 0:tracker2 = BYTETracker(self.par_args, frame_rate=3)track_now = tracker2.update(results, (pic_h,pic_w),(pic_h,pic_w), self.par_args)track_last = tracker2.update(last_box, (pic_h,pic_w),(pic_h,pic_w), self.par_args)last_ids = set(t.track_id for t in track_last)b_ids = set(t.track_id for t in track_now)# 找出 a 中比 b 多出来的所有 track_idextra_ids = last_ids - b_ids# 根据 track_id 提取出对应的完整对象(如 STrack)extra_targets = [t for t in track_last if t.track_id in extra_ids]for t in extra_targets:x1, y1, w, h = t.tlwhprint('add box', frame_id,x1, y1, w, h)box_lost=np.asarray([x1, y1, x1 + w, y1 + h,t.score,0])results = np.vstack([results, box_lost])last_box=resultst1 = time.time()frame = self.yolo_byte_track(results, frame)print(f"{frame_id} det_track time {time.time() - t0:.3f}s track_time {time.time() - t1:.3f}s")if np.prod(frame.shape[:2]) > 1000 * 1300:x_scale = np.sqrt(1000 * 1200 / np.prod(frame.shape[:2]))frame = cv2.resize(frame, None, fx=x_scale, fy=x_scale, interpolation=cv2.INTER_AREA)cv2.imshow("YOLO Track", frame)if cv2.waitKey(0) & 0xFF == 27:   # Esc to quitbreak# 写入输出视频out.write(frame)frame_id += 1def detect_image_yolo(yolo_model,image, imgsz=640, conf=0.4, min_area=60*40, max_len=0):with torch.no_grad():results = yolo_model(image, verbose=False, imgsz=imgsz, conf=conf)cls = results[0].boxes.cls.int().cpu()indices = torch.where(cls == 0)[0]  # 只保留 person 类别if len(indices) == 0:return np.empty((0, 6))  # 返回空但保持 shape 正确labels = results[0].boxes.cls[indices]boxes = results[0].boxes.xyxy[indices]scores = results[0].boxes.conf[indices]if len(boxes) == 0:return np.empty((0, 6))boxes = boxes.float()keep_indices = torchvision.ops.nms(boxes, scores, iou_threshold=0.5)boxes = boxes[keep_indices]scores = scores[keep_indices]labels = labels[keep_indices]#面积过滤areas = (boxes[:, 2] - boxes[:, 0]) * (boxes[:, 3] - boxes[:, 1])area_mask = areas >= min_areaboxes = boxes[area_mask]scores = scores[area_mask]labels = labels[area_mask]if len(boxes) == 0:return np.empty((0, 6))# 转换为 numpy 并拼接成 ByteTrack 格式boxes = boxes.cpu().numpy()scores = scores.cpu().numpy()labels = labels.cpu().numpy()dets = np.concatenate([boxes, scores[:, None], labels[:, None]], axis=1)  # [N, 6]return detsif __name__ == "__main__":mp4_path = r"C:\Users\Administrator\Videos\yundong\20250226162704517\20250226162704517.mp4"mp4_path = r"F:\data\lanqiu\150_30\150_30.mp4"mp4_path = r"E:\data\tiaosheng\0706\5s.mp4"video_id = os.path.basename(mp4_path).split(".")[0]  # 从路径中提取视频 IDyolo_path= r"F:\BaiduNetdiskDownload\tiaosheng_new\model\best_new.pt"yolo_cls = YOLO_Class(yolo_path)yolo_cls.get_bytetrack_bbox(mp4_path, video_id, output_path=f"{video_id}_tracked.mp4", debug=True)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/914672.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/914672.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

安装Keycloak并启动服务(macOS)

前提&#xff1a;电脑已经安装Java 17 1、下载Keycloak 2、下载完后解压缩&#xff0c;使用文本编辑器修改配置文件&#xff08;keycloak/conf/keycloak.conf&#xff09; # Basic settings for running in production. Change accordingly before deploying the server. # …

汽车动力转向器落锤冲击试验台

落锤冲击试验台主要用于扣件减振量的测试&#xff0c;采用电动锚链提锤结构&#xff0c;控制精度高&#xff0c;定位准确。采用伺服电机减速机驱动&#xff0c;避免提锤加速和到位减速时的冲击&#xff0c;具有多重安全保护功能&#xff0c;防止二次冲击装置。主机框架采用上下…

Linux系统集群部署模块之Keepalived双机热备

目录 概述 一、keepalived安装 二、配置文件 三、 其他配置项说明 四、名词解释 五、高阶使用 1、介绍 2、keepalived主要作用 3、工作在三层、四层和七层原理 4、健康状态检测方式 4.1 HTTP服务状态检测 4.2 TCP端口状态检测&#xff08;使用TCP端口服务基本上都可…

TDengine 使用最佳实践(1)

目录 数据建模 单列模型 多列模型 分库分表 边界限制 资源规划 CPU 主频 CPU 核数 内存分类 内存计算 CPU 内存比例 磁盘 网络 下一篇 TDengine 使用最佳实践&#xff08;1&#xff09; 关于 TDengine TDengine 是一款专为物联网、工业互联网等场景设计并优化的大数据平台&am…

Java行为型模式---责任链模式

责任链模式基础概念责任链模式&#xff08;Chain of Responsibility Pattern&#xff09;是一种行为型设计模式&#xff0c;其核心思想是将请求的发送者和接收者解耦&#xff0c;使多个对象都有机会处理请求。这些对象连接成一条链&#xff0c;请求沿着链传递&#xff0c;直到有…

嵌入式学习笔记- 结构体名字被赋值时是整体内容赋值

结构体变量名被赋值时&#xff0c;‌不是赋值的地址&#xff0c;而是执行对整个结构体内容的复制&#xff08;值拷贝&#xff09;‌直接赋值是成员级复制‌ 当使用 s2 s1; 形式的赋值时&#xff08;其中 s1 和 s2 是同类型结构体变量&#xff09;&#xff0c;系统会‌逐成员复…

基于UDP/IP网络游戏加速高级拥塞控制算法(示意:一)

/* ███████╗ 基于UDP/IP网络游戏加速高级拥塞控制算法&#xff08;示意&#xff1a;一&#xff09; ███████╗ */#pragma once#include <iostream> #include <vector> #include <deque> #include <cmath> #include <algorithm> …

【YOLOv11-目标检测】06-模型部署(C++)

上一节课,我们学习了模型的预测。那么,如何用C++部署呢? 克隆项目 进入cmd,进入自己的项目文件夹,然后git clone项目: git clone https://github.com/Geekgineer/YOLOs-CPP 进入到YOLOs-CPP文件夹: 配置环境 ONNX Runtime 后续构建项目的时候,会自动下载,因此,我…

【第零章编辑器开发与拓展】

前言&#xff1a;对编辑器拓展与开发可以节省很多时间&#xff0c;提高开发效率&#xff0c;比如技能编辑器&#xff0c;关卡编辑器这种。当然这只是编辑器开发的一些典型应用&#xff0c;它能做不止这些。学习完这个之后&#xff0c;我们可以开发项目需要的工具。我本意在编辑…

使用 mongoimport 导入本地 JSON 文件到 MongoDB 及数据查看指南

在项目中&#xff0c;我们经常需要将本地 JSON 文件批量导入 MongoDB 数据库。本文以 Ubuntu 22.04 环境为例&#xff0c;详细记录了如何安装 mongoimport 工具、正确导入多个 JSON 文件&#xff0c;以及查看导入后的数据。一、环境介绍操作系统&#xff1a;Ubuntu 22.04.5 LTS…

新手向:Python数据处理Excel报表自动化生成与分析

Python实现Excel报表自动化系统全流程指南本文将详细介绍如何使用Python实现一个完整的Excel报表自动化系统&#xff0c;涵盖从数据清洗、分析到可视化报表生成的全流程。本教程面向Python初学者&#xff0c;通过实际案例讲解pandas和openpyxl库的核心用法。系统概述Excel报表自…

【第六节】docker可视化工具portainer安装

该文章参考了这篇文章https://zhuanlan.zhihu.com/p/27740131259portainer是一个基于网页的docker可视化管理工具&#xff0c;试想一下我们怎么登录路由器管理界面的&#xff0c;异曲同工。那么就需要在服务器的docker内安装portainer&#xff0c;然后在我们的开发机或者说工作…

使用 Certbot 申请和自动续签 Let’s Encrypt 的免费 SSL 证书

一. Let’s Encrypt 介绍 Let’s Encrypt 是当前最常用的免费 HTTPS 证书生成工具之一。该服务由非营利组织提供&#xff0c;致力于为全球范围内的网站提供便捷的自动化证书颁发服务。虽然 Let’s Encrypt 证书的有效期只有90天&#xff0c;但是可以自动续期&#xff0c;这使得…

【kubernetes】--controller(DaemonSet)

Kubernetes DaemonSet 控制器详解 它确保集群中所有(或部分)节点上都运行一个 Pod 的副本。当有新节点加入集群时&#xff0c;DaemonSet 会自动在新节点上创建 Pod&#xff1b;当节点从集群中移除时&#xff0c;这些 Pod 也会被垃圾回收。 DaemonSet 的核心特性 每个节点一个 P…

内测分发平台应用的异地容灾和负载均衡处理和实现思路

内测分发平台应用的异地容灾和负载均衡处理和实现思路如下&#xff1a;一、异地容灾1.风险评估和需求分析&#xff1a;对现有的IT基础设施进行全面的风险评估和需求分析&#xff0c;评估潜在风险和灾害的可能性&#xff0c;以及确定业务和数据的关键性。2.设计备份架构&#xf…

【Vue】浏览器缓存 sessionStorage、localStorage、Cookie

嘿&#xff0c;各位 Vue 开发者们&#xff01;今天咱们来好好聊聊浏览器里的三种缓存方式&#xff1a;sessionStorage、localStorage 和 Cookie。在实际开发中&#xff0c;合理运用这些缓存能让我们的应用性能大幅提升&#xff0c;同时避免一些不必要的问题。下面就跟着我的笔记…

c#如何将不同类型的数据存储到一起

在 C# 中&#xff0c;存储不同类型的数据有多种方式&#xff0c;具体选择取决于你的需求&#xff08;类型安全、性能、灵活性等&#xff09;。以下是常见的解决方案及其适用场景&#xff1a;1. 使用 object 类型&#xff08;装箱 / 拆箱&#xff09;将所有数据转换为基类 objec…

超唯美治愈风卡通插画PPT模版

海洋卡通风治愈系PPT模版&#xff0c;儿童可爱治愈可爱PPT模版&#xff0c;治愈风商务通用PPT模版&#xff0c;治愈系课件PPT模版&#xff0c;治愈风插画PPT模版&#xff0c;超唯美治愈风PPT模版&#xff0c;可爱插画治愈系女孩PPT模版 超唯美治愈风卡通插画PPT模版&#xff1a…

el-tooltip 快速滚动的时候出现残影如何解决 vue3

<el-tooltip:disabled"isScrolling" <!-- 新增滚动状态绑定 -->:popper-options"{ modifiers: [{ name: computeStyles, options: { adaptive: false }] }"effect"dark":content"label.name"placement"right-start"…

【经典面经】C++新特性 TCP完整收发数据 TLS1.2 TLS1.3

文章目录cpp新特性C11C14C17C20tcp如何保证完整收发数据结论1. **面向连接的三次握手**2. **字节序号与确认机制**3. **校验和&#xff08;Checksum&#xff09;**4. **超时重传与快速重传**5. **滑动窗口&#xff08;流量控制&#xff09;**6. **数据重组与排序**7. **四次挥手…