7 Table for the 0.95 quantile of the chi-square distribution with N degrees of 8 freedom (contains values for N=1, ..., 9). Taken from MATLAB/Octave's chi2inv 9 function and used as Mahalanobis gating threshold. 25 A simple Kalman filter for tracking bounding boxes in image space. 27 The 8-dimensional state space 29 x, y, a, h, vx, vy, va, vh 31 contains the bounding box center position (x, y), aspect ratio a, height h, 32 and their respective velocities. 34 Object motion follows a constant velocity model. The bounding box location 35 (x, y, a, h) is taken as direct observation of the state space (linear 56 """Create track from unassociated measurement. 61 Bounding box coordinates (x, y, a, h) with center position (x, y), 62 aspect ratio a, and height h. 67 Returns the mean vector (8 dimensional) and covariance matrix (8x8 68 dimensional) of the new track. Unobserved velocities are initialized 72 mean_pos = measurement
73 mean_vel = np.zeros_like(mean_pos)
74 mean = np.r_[mean_pos, mean_vel]
85 covariance = np.diag(np.square(std))
86 return mean, covariance
89 """Run Kalman filter prediction step. 94 The 8 dimensional mean vector of the object state at the previous 97 The 8x8 dimensional covariance matrix of the object state at the 103 Returns the mean vector and covariance matrix of the predicted 104 state. Unobserved velocities are initialized to 0 mean. 117 motion_cov = np.diag(np.square(np.r_[std_pos, std_vel]))
120 covariance = np.linalg.multi_dot((
121 self.
_motion_mat, covariance, self._motion_mat.T)) + motion_cov
123 return mean, covariance
126 """Project state distribution to measurement space. 131 The state's mean vector (8 dimensional array). 133 The state's covariance matrix (8x8 dimensional). 138 Returns the projected mean and covariance matrix of the given state 147 innovation_cov = np.diag(np.square(std))
150 covariance = np.linalg.multi_dot((
152 return mean, covariance + innovation_cov
154 def update(self, mean, covariance, measurement):
155 """Run Kalman filter correction step. 160 The predicted state's mean vector (8 dimensional). 162 The state's covariance matrix (8x8 dimensional). 163 measurement : ndarray 164 The 4 dimensional measurement vector (x, y, a, h), where (x, y) 165 is the center position, a the aspect ratio, and h the height of the 171 Returns the measurement-corrected state distribution. 174 projected_mean, projected_cov = self.
project(mean, covariance)
176 chol_factor, lower = scipy.linalg.cho_factor(
177 projected_cov, lower=
True, check_finite=
False)
178 kalman_gain = scipy.linalg.cho_solve(
179 (chol_factor, lower), np.dot(covariance, self._update_mat.T).T,
180 check_finite=
False).T
181 innovation = measurement - projected_mean
183 new_mean = mean + np.dot(innovation, kalman_gain.T)
184 new_covariance = covariance - np.linalg.multi_dot((
185 kalman_gain, projected_cov, kalman_gain.T))
186 return new_mean, new_covariance
189 only_position=
False):
190 """Compute gating distance between state distribution and measurements. 192 A suitable distance threshold can be obtained from `chi2inv95`. If 193 `only_position` is False, the chi-square distribution has 4 degrees of 194 freedom, otherwise 2. 199 Mean vector over the state distribution (8 dimensional). 201 Covariance of the state distribution (8x8 dimensional). 202 measurements : ndarray 203 An Nx4 dimensional matrix of N measurements, each in 204 format (x, y, a, h) where (x, y) is the bounding box center 205 position, a the aspect ratio, and h the height. 206 only_position : Optional[bool] 207 If True, distance computation is done with respect to the bounding 208 box center position only. 213 Returns an array of length N, where the i-th element contains the 214 squared Mahalanobis distance between (mean, covariance) and 218 mean, covariance = self.
project(mean, covariance)
220 mean, covariance = mean[:2], covariance[:2, :2]
221 measurements = measurements[:, :2]
223 cholesky_factor = np.linalg.cholesky(covariance)
224 d = measurements - mean
225 z = scipy.linalg.solve_triangular(
226 cholesky_factor, d.T, lower=
True, check_finite=
False,
228 squared_maha = np.sum(z * z, axis=0)
def initiate(self, measurement)
def update(self, mean, covariance, measurement)
def project(self, mean, covariance)
def predict(self, mean, covariance)
def gating_distance(self, mean, covariance, measurements, only_position=False)