リアルタイム映像の検出・追跡パイプラインの設計と検証
追跡器では表示用の外挿制限と対応付け用予測を分離する
3日前
物体追跡で、画面上の枠飛びを抑えるために外挿距離をクランプする場合、その同じ予測を次フレームの対応付けにも使うと、高速移動や推論間隔の伸びで正しい候補との IoU が閾値を下回り、既存トラックが寿命内に残る間に新しいトラックが増える。表示の安定化が、追跡の同一性を壊す形になる。
表示用の予測は UI 安全のために距離を制限し、対応付けには未クランプの運動予測、または速度と経過時間に応じた探索ゲートを使う。表示制約と association の責務を分離し、片方の調整がもう片方の探索範囲を暗黙に変えないようにする。
回帰テストは単発の表示外挿だけで終えず、上限へ到達した後の次回更新まで含める。同一対象の ID が維持されること、旧トラックと新トラックが同時に安定扱いにならないこと、低速・高速・長い推論間隔の境界を確認する。
1画像1対象の検証器を領域候補のROIに適用する構成では、失敗時に拡大ROIで再試行してから失敗と数える
7日前
「対象全体が画像に収まっていること」を前提とする検証器(1画像1ドキュメントの四隅推定モデルなど)を、軽量検出の領域候補から切ったROIに適用する構成には構造的な相性問題がある。領域候補が対象の一部(多色デザインで断片化したクラスタなど)しか捕えていないと、候補基準の定倍拡大ROIに対象全体が入らず、検証器は常に NULL を返す。この失敗をそのままカウントすると、実在する対象のトラックが繰り返し破棄され、特定デザインの対象だけ検出できない症状になる。
判断基準
- 検証失敗をジャンクの証拠と数える前に、より大きいROI(例: 通常2倍→失敗時3倍強)で一度だけ再試行する。過大側がsafeな検証器(全画面適用でも成立するモデル)でのみ使える手。
- 再試行は失敗時のみに限定すれば推論コストの増加は失敗経路だけに留まる。拡大ROIが元ROIとほぼ同じ(画面端でクランプ済み)なら再試行をスキップする。
- 拡大ROIは隣の対象を拾う可能性があるので、同一対象への多重枠統合(IoUマージ)と乗り移りガードが後段にあることを前提にする。
- 検証方法: 対象別の検出率を正解位置つきで採点すると、この型の偏り(特定デザインだけ低い)が検出できる。
カメラ追跡UIの動作検証は、実写真の上を仮想カメラが動く正解位置つき合成モーションで真値採点する
7日前
実機録画のリプレイ検証は症状の再現には有効だが、2つの限界がある。(1) 毎フレームの対象の正解座標がなく、「枠が対象から外れている(ゴースト)」「対象が見えているのに検出できていない」を厳密に採点できない。(2) モーションの種類(上下パン・急パン・手ブレ・ズーム)を網羅できず、録画に含まれる動きしか検証できない。
解決策: 対象が複数写った高解像度の実写真を「世界」にし、その上を仮想カメラ(ビューポートのクロップ+リサイズ)が動くフレーム列を生成する。ビューポートの軌道は自分で制御するので、各対象の正解座標と可視率が毎フレーム式で導出できる。
手順
- 世界写真上の対象位置を一度だけアノテーション(検出モデルの単体適用で自動化できる)。
- モーションパターンをキーフレームや乱数歩行で定義(例: 静止→急移動→静止の繰り返し、smoothstep の往復パン、分散固定のランダムウォーク手ブレ、ズームはビューポート幅の変化)。乱数はシード固定で再現可能にする。
- 生成動画を本物の実装へフェイクカメラ入力し、表示された枠をサンプリング。正解と突き合わせて「ゴースト率(どの可視対象とも重ならない枠)」「完全可視時の対象別検出率」「同一対象への多重枠数」を採点する。
効用・注意
- 対象別の検出率が出るため、「特定デザインの対象だけ検出率が低い」型の偏り(例: 多色デザインで領域提案が断片化する)を発見できる。集計値だけでは埋もれる。
- モーション合成はモーションブラーを含まないので、ブラー起因の検出低下は別途実録画で確認する。
- 実録画リプレイ(症状再現)・移植シミュレータ(パラメータ探索)と相互補完であり、置換ではない。
カメラ系機能の実機不具合は、録画をフェイクカメラにして本物の実装へ流すブラウザリプレイで検証する
7日前
カメラ映像を扱う機能の実機不具合を、検出ロジックを別言語・別環境に移植したシミュレータだけで調査すると、2つの盲点が残る。(1) 移植ずれ: 検証しているのは「ロジックの写し」であって本番コードそのものではない。(2) 実レイテンシ: 推論時間やループ周期を仮定値で置くため、速度起因の症状(表示遅延・ゴースト残存)を再現できない。
この盲点は、実機録画をフェイクカメラ入力にして本物の実装をブラウザテストで等速再生することで塞げる。
手順
- 実機の画面録画から UI と描画オーバーレイを除去(クロップ + 近傍色 inpaint)し、動画ファイル化する。
- ブラウザテスト内でその動画を canvas へ描画し、canvas の captureStream を getUserMedia のモック戻り値にして、コンポーネントには本物のカメラと区別させない。
- 検出結果はオーバーレイ canvas の画素から抽出する(描画色のマスク→連結成分で「表示中の枠数と位置」をサンプリング)。タイムライン化すれば「初回表示までの秒数」「枠数の推移」「堆積の有無」が数値で出る。
- 重い推論関数をテスト側でラップ(モジュールモックで実体を呼びつつ計測)し、実レイテンシを実測する。さらに人工遅延を注入すれば低速端末を模擬でき、「遅い端末でも破綳しないか」を手元で検証できる。
適用条件・注意
- 移植シミュレータ(パラメータ探索が速い)とは補完関係。探索は移植側、最終確認とレイテンシ実測は本物リプレイ、と役割分担すると速い。
- 検証マシンの CPU は実端末より速いので、絶対値ではなく「遅延注入あり/なしの振る舞い差」で判断する。フレーム数基準の閾値があると遅延注入で意味が変わる点に注意(閾値は実時間基準にしておく)。
- 録画に個人情報(他人の名刺等)が含まれる場合、動画とテストはリポジトリにコミットせずローカル専用の診断ハーネスとして運用する。
- 重い推論でメインスレッドが飽和するとサンプリングタイマーが間引かれる。サンプルは回数でなくタイムスタンプ付きで記録する。
重い検証器と軽量トラッカーの合成では検証結果を追跡へ追従させ、表示消灯とトラック破棄を分離する
7日前
リアルタイム映像で「高頻度の軽量検出(存在検出・追跡)」と「低頻度の重い検証器(MLモデルなどによる精密な形状推定)」を組み合わせる構成では、検証結果の座標を検証成功時にしか更新しないと、カメラや対象が動いた瞬間に確定表示が画面座標へ凍結されたまま取り残される。巡回検証の再訪間隔はトラック数×推論時間に比例して延びるため、対象が増えるほどゴースト(ずれた位置に残る確定表示)が長く残り、新しい位置には新しい表示が生えて堆積する。生存時間を縮めるだけの対処は、今度は瞬断のたびに表示が破棄・再検証されて点滅と再生成コストが増える逆側の失敗になる。
判断基準
- 検証済みの精密形状は、毎フレームの軽量追跡の移動量で平行移動させて追従させる。位置の鮮度は軽量側が、形状の正確さは重い側が担う分担にし、再検証は「復元」ではなく「補正」の役割に格下げする。
- 「表示を消す閾値」と「トラックを破棄する閾値」を分離する。追跡を見失ったら表示は短時間(数百ms相当)で畳み、トラック自体は長め(1秒相当)に生かす。追跡が復帰したときは再検証なしで即再表示でき、ゴースト表示の抑制と点滅回避を両立できる。
- 非同期検証には stale ガードを置く。検証開始時点から対象が動いていたら、届いた結果の適用も失敗のカウントも捨てる(古い位置の結果で追従済みの表示を引き戻したり、ROIずれ由来の失敗で実在対象を破棄したりしない)。
- 検証結果を移動平均で混ぜるのは前回結果と十分重なる(同一対象の微修正である)場合に限る。重なりが小さい結果は別対象への乗り移りとみなし置換する。頂点ごとの補間は乗り移り時に自己交差した多角形を過渡表示する。
検証方法
実機録画をフレーム列化してパイプライン全体をオフラインで再生し、「ゴースト残存フレーム率(追跡の裏付けを失ったまま表示されたフレームの割合)」「表示集合の変化回数」「トラック再生成数」を新旧構成で比較する。ゴースト削減が表示の点滅増(変化回数・再生成の悪化)で買われていないかを、動きの多い録画と静止録画の両方で確認する。