DeepSORTアルゴリズムのアーキテクチャ解析
DeepSORTは、検出層、特徴抽出層、データ関連付け層の3層構造を採用しています。検出層ではYOLOやFaster R-CNNなどの検出器で境界ボックスを取得し、非最大値抑制(NMS)処理を行います。特徴抽出層ではResNetやMobileNetなどのディープラーニングモデルで128次元の特徴ベクトルを生成します。
ハンガリーアルゴリズムの応用
コスト行列の構築には以下のような要素が含まれます:
| コストタイプ | 計算式 | 適用シーン |
|---|---|---|
| IOU距離 | 1 - IOU(検出ボックス, 予測ボックス) | 連続的な運動のシーン |
| マハラノビス距離 | (検出ボックス-予測ボックス)^T * 逆相関行列 * (検出ボックス-予測ボックス) | 運動不確実性を考慮するシーン |
| コサイン距離 | 1 - 特徴ベクトルの内積 | 長期的な遮蔽後の再識別 |
以下のコードは階層マッチング戦略を示しています:
def match_tracks_with_detections(tracks, detections):
matching_costs = calculate_costs(tracks, detections)
matched_indices = linear_assignment(matching_costs)
confirmed_matches = []
for t_idx, d_idx in zip(matched_indices[0], matched_indices[1]):
if matching_costs[t_idx, d_idx] < threshold:
confirmed_matches.append((tracks[t_idx], detections[d_idx]))
return confirmed_matches
カルマンフィルタの動的予測メカニズム
カルマンフィルタは8次元の状態ベクトルを管理します:
- [x, y, a, h, vx, vy, va, vh]
カルマンフィルタの実装例:
class KalmanPredictor:
def __init__(self):
self.state_transition = np.array([...]) # 状態遷移行列
self.observation = np.array([...]) # 観測行列
self.process_noise = np.array([...]) # プロセスノイズ共分散
self.measurement_noise = np.array([...]) # 観測ノイズ共分散
self.covariance = np.eye(8) # 状態共分散行列
def predict(self, state):
state = self.state_transition @ state
self.covariance = self.state_transition @ self.covariance @ self.state_transition.T + self.process_noise
return state
def update(self, state, observation):
innovation = observation - self.observation @ state
innovation_covariance = self.observation @ self.covariance @ self.observation.T + self.measurement_noise
kalman_gain = self.covariance @ self.observation.T @ np.linalg.inv(innovation_covariance)
state = state + kalman_gain @ innovation
self.covariance = (np.eye(8) - kalman_gain @ self.observation) @ self.covariance
return state
アルゴリズムの協調的なエンジニアリング
以下はトラック管理の状態遷移図です:
stateDiagram
[*] --> Provisional: 新規検出
Provisional --> Confirmed: Nフレーム連続マッチ成功
Provisional --> Removed: マッチ失敗
Confirmed --> Removed: Mフレーム連続マッチ失敗
Confirmed --> Confirmed: 持続的なマッチ
以下は主要なクラス構造です:
class ObjectTrack:
def __init__(self, detection_data):
self.predictor = KalmanPredictor()
self.visual_features = [detection_data.feature]
self.identifier = generate_unique_id()
self.lifetime = 1
self.status = 'Provisional'
class TrackingSystem:
def __init__(self):
self.active_tracks = []
self.max_lifetime = 30
self.confirm_threshold = 3
def update(self, new_detections):
# すべてのトラックの予測
for track in self.active_tracks:
track.predict()
# マッチングと更新
matched_pairs = self.match(new_detections)
self.update_confirmed_matches(matched_pairs)
self.handle_unmatched_tracks()
# 新規トラックの生成
self.add_new_tracks(new_detections)
# 無効トラックのクリーンアップ
self.remove_expired_tracks()
パフォーマンス最適化とパラメータ調整
主なパラメータの推奨値:
| パラメータ名 | 推奨値 | 役割 | 調整戦略 |
|---|---|---|---|
| max_dist | 0.2-0.4 | 外観マッチング閾値 | 値が小さいほどマッチングが厳しくなる |
| max_iou_dist | 0.7-0.9 | IOUマッチング閾値 | 目標の運動速度に応じて調整 |
| max_lifetime | 30-90 | トラック保持フレーム数 | シーン変化頻度に応じて調整 |
| confirm_threshold | 3-5 | 確認に必要な連続マッチ数 | 反応速度と安定性のバランス |
| feature_cache_size | 100-200 | 特徴キャッシュサイズ | メモリと精度のトレードオフ |