這個(gè)模塊主要是用于跟蹤算法的,用的是kalman filter+級(jí)聯(lián)檢測(cè)目標(biāo),基本算法是畫(huà)軌跡,根據(jù)軌跡的情況,判斷是否新的id,比如軌跡斷開(kāi)了30幀以上,判斷這個(gè)軌跡delete了;(如果我躲在樹(shù)后面幾分鐘再出來(lái),會(huì)不會(huì)判斷我是兩個(gè)人? 不會(huì),除了軌跡的級(jí)聯(lián)匹配,還用到了tf的特征判斷,會(huì)把每個(gè)人的特征cache保存下來(lái),用來(lái)比較是否兩個(gè)人,一個(gè)id對(duì)應(yīng)一個(gè)特征,再用tensorflow進(jìn)行相似度比較,tensorflow的數(shù)據(jù)集釋Mars的,有100W張圖片,ID SW的錯(cuò)誤比較低,除非是模糊的人像 )
# vim: expandtab:ts=4:sw=4
#單個(gè)目標(biāo)跟蹤狀態(tài)的枚舉類型。
新建的跟蹤是被歸類為“暫定”直到收集到足夠的證據(jù)。
然后,軌道狀態(tài)更改為“確認(rèn)”。
不再活著的軌跡被分類為'刪除',以標(biāo)記他們從一組活躍刪除。
class TrackState:
"""
Enumeration type for the single target track state. Newly created tracks are
classified as `tentative` until enough evidence has been collected. Then,
the track state is changed to `confirmed`. Tracks that are no longer alive
are classified as `deleted` to mark them for removal from the set of active
tracks.
"""
# 三種狀態(tài) 嘗試性的,確定的,被刪除的
Tentative = 1
Confirmed = 2
Deleted = 3
class Track:
"""
# 具有狀態(tài)空間的單個(gè)目標(biāo)軌道(x,y,A,H)和相關(guān)聯(lián)速度,
其中“(x,y)”是bbox的中心,A是高寬比和“H”是高度。
A single target track with state space `(x, y, a, h)` and associated
velocities, where `(x, y)` is the center of the bounding box, `a` is the
aspect ratio and `h` is the height.
Parameters
----------
mean :
# 初始狀態(tài)分布的平均向量。
Mean vector of the initial state distribution.
covariance : #協(xié)方差
# 初始狀態(tài)分布的協(xié)方差矩陣
Covariance matrix of the initial state distribution.
track_id : int
# 唯一的軌跡ID
A unique track identifier.
n_init : int
# 在軌道設(shè)置為confirmed之前的連續(xù)檢測(cè)幀數(shù)。
當(dāng)一個(gè)miss發(fā)生時(shí),軌道狀態(tài)設(shè)置為Deleted幀。
Number of consecutive detections before the track is confirmed.
The track state is set to `Deleted` if a miss occurs within the first
`n_init` frames.
max_age : int
# 在偵測(cè)狀態(tài)設(shè)置成Deleted前,最大的連續(xù)miss數(shù)。
The maximum number of consecutive misses before the track state is set to `Deleted`.
feature : Optional[ndarray]
# 特征向量檢測(cè)的這條軌道的起源。
如果為空,則這個(gè)特性被添加到'特性'緩存中。
Feature vector of the detection this track originates from. If not None,
this feature is added to the `features` cache.
trackid:
軌跡ID。
---------
Attributes #屬性
mean : ndarray #均值:
# 初始分布均值向量。
Mean vector of the initial state distribution.
covariance : ndarray # 協(xié)方差:
# 初始分布協(xié)方差矩陣。
Covariance matrix of the initial state distribution.
track_id : int
A unique track identifier.
hits : int
#測(cè)量更新的總數(shù)。
Total number of measurement updates.
hit_streak : int
# 自上次miss之后,連續(xù)測(cè)量更新的總數(shù)。(更新一次+1)
Total number of consective measurement updates since last miss.
age : int
#從開(kāi)始的總幀數(shù)
Total number of frames since first occurance.
time_since_update : int
# 從上次的測(cè)量更新完后,統(tǒng)計(jì)的總幀數(shù)
Total number of frames since last measurement update.
state : TrackState
# 當(dāng)前的偵測(cè)狀態(tài)
The current track state.
features : List[ndarray]
# 特性的緩存。在每個(gè)度量更新中,相關(guān)的特性
向量添加到這個(gè)列表中。
A cache of features. On each measurement update, the associated feature
vector is added to this list.
"""
# 初始化各參數(shù)
def __init__(self, mean, covariance, track_id, n_init, max_age,
feature=None):
self.mean = mean
self.covariance = covariance
self.track_id = track_id
self.hits = 1
self.hit_streak = 1
self.age = 1
self.time_since_update = 0
self.state = TrackState.Tentative
self.features = []
if feature is not None:
self.features.append(feature)
self._n_init = n_init
self._max_age = max_age
# 將bbox轉(zhuǎn)換成xywh
def to_tlwh(self):
"""Get current position in bounding box format `(top left x, top left y,
width, height)`.
Returns
-------
ndarray
The bounding box.
"""
ret = self.mean[:4].copy()
ret[2] *= ret[3]
ret[:2] -= ret[2:] / 2
return ret
# 獲取當(dāng)前位置以某種格式,不太明白
def to_tlbr(self):
"""Get current position in bounding box format `(min x, miny, max x, max y)`.
Returns
-------
ndarray
The bounding box.
"""
ret = self.to_tlwh()
ret[2:] = ret[:2] + ret[2:]
return ret
# 預(yù)測(cè),基于kalman filter
def predict(self, kf):
"""Propagate the state distribution to the current time step using a
Kalman filter prediction step.
Parameters
----------
kf : kalman_filter.KalmanFilter
The Kalman filter.
"""
self.mean, self.covariance = kf.predict(self.mean, self.covariance)
self.age += 1
self.time_since_update += 1
# 更新。 主要是步進(jìn)和特征,檢測(cè)方法為級(jí)聯(lián)檢測(cè)
def update(self, kf, detection):
"""Perform Kalman filter measurement update step and update the feature
cache.
Parameters
----------
kf : kalman_filter.KalmanFilter
The Kalman filter.
detection : Detection
The associated detection.
"""
self.mean, self.covariance = kf.update(
self.mean, self.covariance, detection.to_xyah())
self.features.append(detection.feature)
self.hit_streak += 1
self.hits += 1
self.time_since_update = 0
if self.state == TrackState.Tentative and self.hits >= self._n_init:
self.state = TrackState.Confirmed
# 標(biāo)記已經(jīng)miss的,如果從更新起miss了_max_age(30)幀以上,
設(shè)置為Deleted
def mark_missed(self):
"""Mark this track as missed (no association at the current time step).
"""
if self.state == TrackState.Tentative:
self.state = TrackState.Deleted
elif self.time_since_update > self._max_age:
self.state = TrackState.Deleted
self.hit_streak = 0
# 設(shè)置三種狀態(tài)
def is_tentative(self):
"""Returns True if this track is tentative (unconfirmed).
"""
return self.state == TrackState.Tentative
def is_confirmed(self):
"""Returns True if this track is confirmed."""
return self.state == TrackState.Confirmed
def is_deleted(self):
"""Returns True if this track is dead and should be deleted."""
return self.state == TrackState.Deleted