基于点之间距离的多目标跟踪

1. 动机

        目标跟踪是计算机视觉领域一种常用的算法,用于将前后帧中的同一个目标关联起来,从而可以针对某一个特定目标进行分析,如对状态进行投票平滑获取更为稳健的结果。

        然而,目前流行的跟踪算法大多是基于检测的bbox之间的IOU来匹配的,这对于某些小目标或者点的检测,IOU通常不是一个好的选择,因为目标太小,很容易使得相邻两帧之间的IOU为0。

        为了解决这个问题,本文提出了一种基于点之间距离的跟踪方法:将目标建模为一个点,通过计算前后帧点之间的距离,利用匈牙利匹配来进行跟踪。

2. 方法

        直接上代码,里面给出了跟踪方法的定义以及一个使用示例:

"""
Test for multi-target tracker
"""import numpy as np
from scipy.optimize import linear_sum_assignment# 定义目标类
class Target:def __init__(self, x, y):self.x = xself.y = yself.id = Noneself.miss_num = 0self.lost = False  # 添加一个标记来表示目标是否丢失# 定义跟踪器类
class Tracker:def __init__(self, max_age=1, thres_dist=100):self.max_age = max_ageself.thres_dist = thres_distself.tracked_targets = []self.last_id = 0# 在下一帧中更新目标位置并使用匈牙利算法进行匹配def update(self, targets):# print([[t.x, t.y] for t in targets])# print([[t.x, t.y] for t in self.tracked_targets])# 计算每个跟踪器与目标之间的相似度(这里使用欧氏距离作为相似度指标)distances = []for target in targets:dist_list = []for tracked_target in self.tracked_targets:if not tracked_target.lost:  # 只考虑未丢失的目标dist = np.sqrt((target[0] - tracked_target.x) ** 2 + (target[1] - tracked_target.y) ** 2)dist_list.append(dist)else:dist_list.append(np.inf)  # 将丢失的目标设置为无穷大距离,避免被匹配distances.append(dist_list)distances = np.asarray(distances)# 使用匈牙利算法进行匹配row_ind, col_ind = linear_sum_assignment(distances)# print(row_ind, col_ind, distances)# 更新匹配成功的目标位置# print(len(self.tracked_targets))for i, j in zip(row_ind, col_ind):if not self.tracked_targets[j].lost and distances[i][j] < self.thres_dist:  # 只更新未丢失的目标位置self.tracked_targets[j].x = targets[i][0]self.tracked_targets[j].y = targets[i][1]else:# 如果目标丢失,继续标记为丢失状态,不进行位置更新,同时累计丢失次数self.tracked_targets[j].miss_num += 1if self.tracked_targets[j].miss_num >= self.max_age:# print("lost", self.tracked_targets[j].id)self.tracked_targets[j].lost = True# 添加新的目标到跟踪列表for j in range(len(targets)):if j not in col_ind:self.create_target(targets[j][0], targets[j][1])# 检测丢失的目标,如果目标丢失超过一定帧数,将其从跟踪列表中删除lost_targets = []for target in self.tracked_targets:if target.lost:lost_targets.append(target)for target in lost_targets:self.tracked_targets.remove(target)def create_target(self, x, y):tar = Target(x, y)tar.id = self.last_idself.tracked_targets.append(tar)self.last_id += 1def get_color_by_id(id):colors = [(255, 0, 0),(255, 255, 0),(255, 0, 255),(30, 140, 100),(0, 255, 0),(0, 50, 200),(100, 0, 30),(100, 100, 0),(20, 10, 200),(20, 250, 100),(145, 0, 90),(15, 10, 190),(15, 100, 100),]index = id % len(colors)return colors[index]if __name__ == '__main__':import cv2from PIL import Imageimport copyimg = np.ones([500, 500, 3]).astype(np.uint8)pil_imgs = [Image.fromarray(img)]# 初始化目标列表preds = [[1, 1], [1, 499], [499, 1], [499, 499]]# 初始化跟踪器tracker = Tracker()# 模拟多帧跟踪过程for i in range(100):# 在每一帧中,随机移动每个目标的位置delta = 10if i in [10, 11, 12, 13]:delta = 30# print([[t.x, t.y] for t in tracker.tracked_targets])preds[0][0] += np.random.randint(0, delta)preds[0][1] += np.random.randint(0, delta)preds[1][0] += np.random.randint(0, delta)preds[1][1] -= np.random.randint(0, delta)preds[2][0] -= np.random.randint(0, delta)preds[2][1] += np.random.randint(0, delta)preds[3][0] -= np.random.randint(0, delta)preds[3][1] -= np.random.randint(0, delta)# print([[t.x, t.y] for t in tracker.tracked_targets])# 更新跟踪器的目标列表tracker.update(copy.deepcopy(preds))# 打印当前帧中每个跟踪到的目标位置# print("frame: {}".format(i))points, ids = [], []for target in tracker.tracked_targets:print("Target {}: ({}, {}); lost: {}".format(target.id, target.x, target.y, target.lost))points.append([target.x, target.y])ids.append(target.id)# cv2.circle(img, [target.x, target.y], point_size, point_color, thickness)cv2.putText(img, str(target.id), [target.x, target.y], cv2.FONT_HERSHEY_SIMPLEX, 0.4,get_color_by_id(target.id), thickness=1, lineType=cv2.LINE_AA)pil_imgs.append(Image.fromarray(img))cv2.imshow('img', img)if cv2.waitKey(30) == ord('q'):break# 创建并保存GIF文件image_0 = pil_imgs[0]image_0.save('track_result.gif', save_all=True, append_images=pil_imgs[1:], duration=30, loop=0)

运行上述代码后,会保存一个GIF文件,展示了多个目标的跟踪结果,如下图:

基于点的多目标跟踪结果

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

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

相关文章

PostgreSQL (Hologres) 日期生成

PostgreSQL 生成指定日期下一个月的日期 &#xff08;在Hologres中&#xff0c;不支持递归查询&#xff09; SELECTto_char(T, YYYYMMDD)::int4 AS date_int,date(T) AS date_str,date_part(year, T)::int4 AS year_int,date_part(month, T)::int4 AS month_int,date_part(da…

C#,简单修改Visual Studio 2022设置以支持C#最新版本的编译器,尊享编程之趣

1 PLS README & CHAPTER 5 用一个超简单的例子说明各版本 C# 的差异。 使用新版本&#xff08;比如C#.11&#xff09;&#xff0c;当然有一定的好处。我们在写程序的时候一般这样&#xff1a; Visual Studio 2022 默认只能这样写&#xff1a; string imageFile Path.C…

centos7中通过minikube安装Kubernetes

minikube是一款开源的Kubernetes集群管理器&#xff0c;它可以帮助您在本地计算机上轻松部署和管理Kubernetes集群。以下是minikube的安装和使用步骤&#xff1a; 安装Docker&#xff1a;如果您还没有安装Docker&#xff0c;可以从Docker官方网站上下载并安装适合您操作系统的…

Linux CentOS+宝塔面板工具结合内网穿透实现网站发布至公网可访问

使用Typecho搭建个人博客网站&#xff0c;并内网穿透实现公网访问 文章目录 使用Typecho搭建个人博客网站&#xff0c;并内网穿透实现公网访问前言1. 安装环境2. 下载Typecho3. 创建站点4. 访问Typecho5. 安装cpolar6. 远程访问Typecho7. 固定远程访问地址8. 配置typecho 前言 …

【高级程序设计】django与网页设计

django安装与配置 使用pip进行Django的安装: pip install djangoconda install django验证django安装成功 import django django.__version__ ## django.get_version()新建一个名称为blog的django项目(project), D:\>cd web-project D:\web-project>django-admi…

使用Pytorch从零开始构建LSTM

长短期记忆&#xff08;LSTM&#xff09;网络已被广泛用于解决各种顺序任务。让我们了解这些网络如何工作以及如何实施它们。 就像我们一样&#xff0c;循环神经网络&#xff08;RNN&#xff09;也可能很健忘。这种与短期记忆的斗争导致 RNN 在大多数任务中失去有效性。不过&a…

实现一个计算机

图片&#xff1a; 实现代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style>body {padding: 20px;font-family: Arial;}.calc-wrap {width: 300px;bor…

设计师不能忽视的几个宝藏图标设计工具

在这个快速变化的时代&#xff0c;设计师对创新和实用工具的需求越来越大。这就要求我们及时跟上潮流&#xff0c;不断探索和尝试最新、最有价值的图标设计工具。只有这样&#xff0c;我们才能在竞争激烈的设计市场中脱颖而出。以下是我们精心挑选的2024年值得一试的图标设计工…

飞书如何接入ChatGPT-打造个人智能问答助手实现无障碍交流

目录 前言 环境列表 1.飞书设置 2.克隆feishu-chatgpt项目 3.配置config.yaml文件 4.运行feishu-chatgpt项目 5.安装cpolar内网穿透 6.固定公网地址 7.机器人权限配置 8.创建版本 9.创建测试企业 10. 机器人测试 总结 前言 在飞书中创建chatGPT机器人并且对话&am…

SQL进阶学习

1.[NISACTF 2022]join-us sql报错注入和联合注入 过滤&#xff1a; as IF rand() LEFT by updatesubstring handler union floor benchmark COLUMN UPDATE & sys.schema_auto_increment_columns && 11 database case AND right CAST FLOOR left updatexml DATABA…

Java【XML 配置文件解析】

前言 最近考试周忙得要死&#xff0c;但我却不紧不慢&#xff0c;还有三天复习时间&#xff0c;考试科目几乎都还没学呢。今天更新一个算是工具类-XML文件的解析&#xff0c;感觉还是挺有用的&#xff0c;之后可以融进自己的项目里。 XML 配置文件解析 0、导入依赖 有点像我…

【C++初阶】第一站:C++入门基础(中)

前言&#xff1a; 这篇文章是c入门基础的第一站的中篇,涉及的知识点 函数重载:函数重载的原理--名字修饰 引用:概念、特性、使用场景、常引用、传值、传引用效率比较的知识点 目录 5. 函数重载 &#xff08;续&#xff09; C支持函数重载的原理--名字修饰(name Mangling) 为什么…