背景を差し替えると輪郭がずれる。原因は測り方を間違えていた
2026年8月31日

オンライン会議で背景を差し替えると、止まっているときはきれいなのに、動いた瞬間だけ輪郭が体から遅れてついてくる。手を上げると、手の形になるのが一拍遅い。
この記事は、その遅れがどこで生まれているのかを測った記録です。最初に測った結果は間違っていました。 測り方を直したら内訳が変わり、打てる手も変わりました。同じ症状を追いかけている場合、測り方から疑ったほうが早いかもしれません。
起きていること
背景の切り抜きは、毎フレームこの順で進みます。
- カメラの映像を小さく縮めて入力を作る
- AIモデルに通して「どこが人か」のマスクを得る
- マスクをGPUから読み戻す
- マスクを使って人物と背景を合成する
このうち2の推論が重い。カメラは滑らかに動いているのに、マスクの更新だけが追いつかない。 だから止まっていれば合っていて、動くとずれます。
対策を考えるには、1〜4のどこに時間が乗っているかを知る必要があります。そこで各段階の時間を測りました。
最初の測定は間違っていた

素直に測ると、こういうコードになります。
t0 = 現在時刻
モデルを実行して待つ
t1 = 現在時刻 ← 推論時間 = t1 - t0 のつもり
マスクを読み戻す
t2 = 現在時刻 ← 転送時間 = t2 - t1 のつもり
この測り方で出た結果は「読み戻しが6割」でした。だとすれば、マスクの解像度を下げて転送量を減らせば速くなるはずです。
ところが、解像度を下げても体感がほとんど変わりませんでした。
原因は測り方でした。モデルの実行を待つ関数が、GPUの計算が終わる前に返っていたのです。返ってきた時点では計算がまだ走っているので、その続きの時間が次の区間(転送)に流れ込む。推論時間を転送時間として数えていたことになります。
直し方は、推論と転送の間に「GPUの計算が終わったことを確かめる点」を差し込むことです。出てきた結果のうち1要素だけを読み出す。1要素なら転送量はほぼゼロですが、読み出すためにはGPUの計算が終わっている必要があるので、そこで待ちが入ります。
モデルを実行して待つ
結果の1要素だけ読み出す ← ここでGPUの完了を待つ
t1 = 現在時刻 ← これが本当の推論時間
マスク全体を読み戻す
t2 = 現在時刻 ← これが本当の転送時間
測り直すと、内訳はひっくり返りました。遅いのは推論そのもので、転送は誤差の範囲でした。読み戻しているデータは746KB。今どきの環境で、これが律速になるはずがなかったのです。
解像度を下げても効かない理由
内訳が分かると、効かない対策の理由も分かります。
マスクの解像度を下げると、減るのは転送量です。転送はもともと支配的ではないので、全体はほとんど動きません。支配的なのは推論なので、そこを減らさない限り効きません。
現在は入力を576ピクセル幅に縮め、モデル内部ではさらに縮めて約346ピクセルで処理しています。この設定で17fps。これ以上入力を小さくすると、今度は髪の毛や指の輪郭が保てなくなります。品質を保てる最小の解像度が、だいたいこのあたりでした。
推論を速くする道は、モデルそのものを軽くするか、実行方式を変えるかです。実行方式のほうは試しました。モデルを作り直してGPU向けの新しい実行環境に載せると、確かに速くはなりました。ただし出てくるマットが正しくありませんでした。 数値の精度を落とした形式にすると、人物と認識できずにマスクが薄くなる。最も濃いはずの部分で、255あるべき値が120程度まで落ちました。速いが使えない、という結果です。
ついでに見つかった、静かなメモリリーク
測定の過程で、別の問題も出てきました。背景を有効にしたまま置いておくと、メモリが1.6GBまで増え続けます。
使っているモデルには条件分岐が含まれていて、そのぶん実行のたびに中間データが残ります。通常の自動解放の仕組みは、非同期の実行を管理の外に置くため、これらを回収しません。毎フレーム少しずつ取り残されて積み上がります。
対策は、実行のたびに範囲を区切り、次のフレームに渡すものだけを明示的に残して、残りをまとめて捨てることです。渡すべきものは、モデルが持っている「前のフレームの状態」だけでした。それ以外はその場で不要になります。
長い会議で使う機能ほど、こういう積み上がりが効いてきます。10分のテストでは出ません。
分かったことと、分からないままのこと
測り直して分かったのはここまでです。
- 遅延の大半は推論そのもので、GPUからの読み戻しではない
- だから解像度を下げても効かない
- 品質を保てる最小の入力は約346ピクセル、そのとき17fps
- 精度を落とした形式は速いが、マットが使い物にならない
「高品質のまま低遅延」には届いていません。 現状は、追従が速い代わりに輪郭が粗いモードと、輪郭がきれいな代わりに追従が遅いモードの2つを持ち、用途で選ぶ形にしています。これを1つにまとめるには、モデル自体を変える必要があります。そこはまだ手をつけていません。
ただ、どこを攻めれば効いてどこを攻めても効かないかは、はっきりしました。 測り方を直すまでは、効かないところを削り続けていたわけで、そのぶんの時間が丸ごと無駄になっていました。
Meetnect はブラウザだけで動くオンライン商談ツールで、背景の切り抜きもブラウザの中で処理しています。映像が外に出ないぶん、こうした制約と正面から付き合うことになります。この記事の数字は、すべて実際に測ってコードに記録したものです。