当前位置:网站首页>deepsort源码解读(四)
deepsort源码解读(四)
2022-07-27 05:24:00 【德林恩宝】
linear_assignment.py
# vim: expandtab:ts=4:sw=4
from __future__ import absolute_import
import numpy as np
from scipy.optimize import linear_sum_assignment as linear_assignment
from . import kalman_filter
INFTY_COST = 1e+5
def min_cost_matching(
distance_metric, max_distance, tracks, detections, track_indices=None,
detection_indices=None):
"""Solve linear assignment problem.
Parameters
----------
distance_metric : Callable[List[Track], List[Detection], List[int], List[int]) -> ndarray
The distance metric is given a list of tracks and detections as well as
a list of N track indices and M detection indices. The metric should
return the NxM dimensional cost matrix, where element (i, j) is the
association cost between the i-th track in the given track indices and
the j-th detection in the given detection_indices.
max_distance : float
Gating threshold. Associations with cost larger than this value are
disregarded.
tracks : List[track.Track]
A list of predicted tracks at the current time step.
detections : List[detection.Detection]
A list of detections at the current time step.
track_indices : List[int]
List of track indices that maps rows in `cost_matrix` to tracks in
`tracks` (see description above).
detection_indices : List[int]
List of detection indices that maps columns in `cost_matrix` to
detections in `detections` (see description above).
Returns
-------
(List[(int, int)], List[int], List[int])
Returns a tuple with the following three entries:
* A list of matched track and detection indices.
* A list of unmatched track indices.
* A list of unmatched detection indices.
"""
if track_indices is None:
track_indices = np.arange(len(tracks))
if detection_indices is None:
detection_indices = np.arange(len(detections))
if len(detection_indices) == 0 or len(track_indices) == 0:
return [], track_indices, detection_indices # Nothing to match.
# 获取代价矩阵, 级联时,基于外观信息和马氏距离得出;iou匹配时,基于iou中的代价计算方式给出
cost_matrix = distance_metric(
tracks, detections, track_indices, detection_indices)
# 将代价矩阵中大于门控阈值的track与detection的关联赋值为最大值,视为忽略该两者关系
cost_matrix[cost_matrix > max_distance] = max_distance + 1e-5
# 级联或者iou匹配都借助匈牙利算法得出匹配的两者索引,格式为(track_id,detection_id)
# 行索引为tracks的索引,列索引为detections的索引
indices = linear_assignment(cost_matrix)
# 分别得出匹配与未匹配的track与detection并返回
matches, unmatched_tracks, unmatched_detections = [], [], []
# unmatched_detections
for col, detection_idx in enumerate(detection_indices):
if col not in indices[:, 1]:
unmatched_detections.append(detection_idx)
# unmatched_tracks
for row, track_idx in enumerate(track_indices):
if row not in indices[:, 0]:
unmatched_tracks.append(track_idx)
# matches
for row, col in indices:
track_idx = track_indices[row] # 匹配的track id
detection_idx = detection_indices[col] # 匹配的detection id
# 如果相应的cost大于阈值max_distance,也视为未匹配成功
if cost_matrix[row, col] > max_distance:
unmatched_tracks.append(track_idx)
unmatched_detections.append(detection_idx)
else:
matches.append((track_idx, detection_idx))
return matches, unmatched_tracks, unmatched_detections
# 级联匹配实现
def matching_cascade(
distance_metric, max_distance, cascade_depth, tracks, detections,
track_indices=None, detection_indices=None):
"""Run matching cascade.
Parameters
----------
distance_metric : Callable[List[Track], List[Detection], List[int], List[int]) -> ndarray
The distance metric is given a list of tracks and detections as well as
a list of N track indices and M detection indices. The metric should
return the NxM dimensional cost matrix, where element (i, j) is the
association cost between the i-th track in the given track indices and
the j-th detection in the given detection indices.
为gated_metric函数
max_distance : float
Gating threshold. Associations with cost larger than this value are
disregarded.
余弦距离的最大阈值
cascade_depth: int
The cascade depth, should be se to the maximum track age.
tracks : List[track.Track]
A list of predicted tracks at the current time step.
detections : List[detection.Detection]
A list of detections at the current time step.
track_indices : Optional[List[int]]
List of track indices that maps rows in `cost_matrix` to tracks in
`tracks` (see description above). Defaults to all tracks.
detection_indices : Optional[List[int]]
List of detection indices that maps columns in `cost_matrix` to
detections in `detections` (see description above). Defaults to all
detections.
Returns
-------
(List[(int, int)], List[int], List[int])
Returns a tuple with the following three entries:
* A list of matched track and detection indices.
* A list of unmatched track indices.
* A list of unmatched detection indices.
"""
# 确认的track索引
# 对于只存在未确认的track,那么track_indices为空
if track_indices is None:
track_indices = list(range(len(tracks)))
if detection_indices is None:
detection_indices = list(range(len(detections)))
unmatched_detections = detection_indices
matches = []
# 级联次数max_age
for level in range(cascade_depth):
if len(unmatched_detections) == 0: # No detections left
break
# 按照time_since_update从小到大排序confirmed track
track_indices_l = [
k for k in track_indices
if tracks[k].time_since_update == 1 + level
]
if len(track_indices_l) == 0: # Nothing to match at this level
continue
# 此处的distance_metric为计算卡尔曼滤波预测的tracks和当前时刻检测到的detections的代价矩阵
# max_distance为代价矩阵的阈值,忽略成本大于此值的关联
matches_l, _, unmatched_detections = \
min_cost_matching(
distance_metric, max_distance, tracks, detections,
track_indices_l, unmatched_detections)
matches += matches_l
# 计算未匹配的track
unmatched_tracks = list(set(track_indices) - set(k for k, _ in matches))
return matches, unmatched_tracks, unmatched_detections
def gate_cost_matrix(
kf, cost_matrix, tracks, detections, track_indices, detection_indices,
gated_cost=INFTY_COST, only_position=False):
"""Invalidate infeasible entries in cost matrix based on the state
distributions obtained by Kalman filtering.
Parameters
----------
kf : The Kalman filter.
cost_matrix : ndarray
The NxM dimensional cost matrix, where N is the number of track indices
and M is the number of detection indices, such that entry (i, j) is the
association cost between `tracks[track_indices[i]]` and
`detections[detection_indices[j]]`.
tracks : List[track.Track]
A list of predicted tracks at the current time step.
detections : List[detection.Detection]
A list of detections at the current time step.
track_indices : List[int]
List of track indices that maps rows in `cost_matrix` to tracks in
`tracks` (see description above).
detection_indices : List[int]
List of detection indices that maps columns in `cost_matrix` to
detections in `detections` (see description above).
gated_cost : Optional[float]
Entries in the cost matrix corresponding to infeasible associations are
set this value. Defaults to a very large value.
only_position : Optional[bool]
If True, only the x, y position of the state distribution is considered
during gating. Defaults to False.
Returns
-------
ndarray
Returns the modified cost matrix.
"""
gating_dim = 2 if only_position else 4
gating_threshold = kalman_filter.chi2inv95[gating_dim]
measurements = np.asarray(
[detections[i].to_xyah() for i in detection_indices])
for row, track_idx in enumerate(track_indices):
track = tracks[track_idx]
gating_distance = kf.gating_distance(
track.mean, track.covariance, measurements, only_position)
cost_matrix[row, gating_distance > gating_threshold] = gated_cost
return cost_matrix
边栏推荐
- Code random notes_ Hash_ 242 effective letter heterotopic words
- 阿里云短信验证第三方接口(快速使用)
- ES6新特性(入门)
- Shell script one click configuration lamp
- Webodm win10 installation tutorial (personal test)
- Soul continues to make efforts to list its social channels in Hong Kong. Why is "soul style social" popular?
- 如何避免漏洞?向日葵远程为你讲解不同场景下的安全使用方法
- 向日葵全面科普,为你的远程控制设备及时规避漏洞
- Create a container that does not depend on any underlying image
- NAT(网络地址转换)
猜你喜欢

What is special about the rehabilitation orthopedic branch of 3D printing brand?

Linux Installation and uninstallation of MySQL

ES6 new features (getting started)

Linux安装Redis操作

What "hard core innovations" does Intel have in the first half of 2022? Just look at this picture!

Linux安装与卸载MySql

多模态数据库 | 星环科技多模数据库ArgoDB“一库多用“,构建高性能湖仓集一体平台

The problem of torch loading custom models

Speech and language processing (3rd ed. draft) Chapter 2 - regular expression, text normalization, editing distance reading notes

DNS域名解析服务
随机推荐
Customer cases | focus on process experience to help bank enterprise app iteration
pycharm在虚拟环境下跑jupyter notebook问题记录
What is special about the rehabilitation orthopedic branch of 3D printing brand?
C语言怎么学?这篇文章给你完整答案
Sok: the faults in our asrs: an overview of attacks against automatic speech recognition
Shell sentence judgment exercise
ES6 new features (getting started)
MangoDB
torch加载自定义模型的问题
A cross domain problem of golang
智能安防视频平台EasyCVR出现通道列表为空情况的原因是什么?
Rsync remote synchronization
Sunflower teaches you how to prevent denial of service attacks?
gin-vue-admin 使用docker容器中的数据库
NAT(网络地址转换)
DHCP的概念和原理
Summary of frequently asked questions in the interview [summarized after painstaking work all night]
FTX Foundation funded 15million to help covid-19 clinical trials, which will affect global public health
LVM and disk quota
Redis fast learning