🎃

オプトインカメラの作り方

2024/12/15に公開

本記事はCyberAgent AI Lab Advent Calender 2024の15日目の記事です.もしよろしければ,前後の記事もご覧ください!
14日目:Rust 製の超高速パッケージマネージャ pixi で ROS 2 に入門する
16日目:プレゼントを公平に配る最適なくじ引きを作ろう!

ひとことで

プライバシーに配慮したカメラ計測手法であるオプトインカメラがどのような仕組みで動いているのかをゆるっと解説します.

オプトインカメラサンプル
オプトインカメラのサンプル.
左:元の映像. 右:UWBのタグデバイスが取り付けられているカゴを持っている人物だけを残した映像.

はじめに

こんにちは.株式サイバーエージェントのAI Labに所属している石毛です.ソフトロボットの研究で博士号をとり,弊社のサイネージ事業部でエンジニアをやった後,現在の組織で屋内測位などの研究をしています(まるで一貫性がない).

センシング技術の一貫で,オプトインカメラというものをつくったので,その仕組について解説しようと思います.ちなみに,論文としても公開しているので,興味があればそちらもご参照ください.

背景

サイバーエージェントはリテールメディア事業に取り組んでいます.小売アプリや店頭サイネージを広告媒体として活用するビジネスです.そこで重要になるのが,店舗に来店されたお客様がどのような行動をしたのかを計測することです.例えば,

  • どの商品エリアに長く滞在していたのか?
  • どの商品で迷っていたのか?
  • サイネージ広告を見たのか?

などです.こういう情報をもとに,広告効果を計測したり,よりコンバージョンにつながりやすい広告を配信したりできると理想的です.こういったデータを取得するには,カメラを使うことがまず考えられと思います.事実,小売業界ではAIカメラの活用が非常に注目されています.

しかし,カメラで取得した来店客の映像(特に顔が映っているもの)は個人情報に該当するので,扱いには細心の注意が必要です.また,顔にモザイクをかけるなどして法律的な問題をクリアしたとしても,自分の買物行動が勝手に記録され,広告配信等に利用されていると思うと心理的な抵抗を感じられるお客様が一定数存在するでしょう.

そこで,映像として撮影されることに同意(オプトイン)した人物だけを記録する仕組みを開発しました.UWB測位とコンピュータービジョンを組み合わせた技術で,小さなタグデバイスを持った人物(オプトインした人)を映像の中から特定し,その人物だけを残した(i.e., それ以外を隠蔽した)映像を生成して記録するというものです.

前提知識

UWB測位

超広帯域(Ultra-Wide Band, UWB)無線通信を活用した測位技術です.数ナノ秒程度の幅の非常に短いパルス信号をやり取りすることで,デバイス間の距離や角度を高精度で測ることが可能です.屋内測位で利用する場合,まずアンカーデバイスを環境に設置し,測位対象(人など)にタグデバイスをもたせます.アンカーデバイスとタグデバイスが通信して相対的な位置関係を測位することで,測位対象の位置を計算することができます.オプトインカメラでは,time-of-flight (ToF)とangle-of-arrival (AoA)を使います.

c.f., UWB(超広帯域)無線通信とは

カルマンフィルタ

ノイジーな観測から,系の状態を推定する技術です.例えば,UWBの信号(観測)にはノイズが載りますが,そこからタグを持っている人間の位置(状態)を推定するのに使います.以下の前提のもと,非常に精度のよい状態推定ができることが知られているので,工学的にとても広く利用されています.

  • 状態遷移モデルがわかっている
  • 状態遷移モデルの誤差がガウス分布に従う
  • 観測ノイズがガウス分布に従う

線形カルマンフィルタの場合,以下の予測と更新の操作を繰り返すことで状態推定を行います.

予測
状態 \mathbf{x}_{t-1}に状態遷移行列\mathbf{F}と制御入力\mathbf{u}_{t}を作用させることで,次のタイムステップの状態\bar{\mathbf{x}}_tと共分散行列\bar{\mathbf{P}}_tを予測するします(すなわち, 事前分布を計算します)

\begin{align} \bar{\mathbf{x}}_{t} &= \mathbf{F} \mathbf{x}_{t-1} + \mathbf{B} \mathbf{u}_{t}\\ \bar{\mathbf{P}}_{t} &= \mathbf{F} \mathbf{P}_{t-1} \mathbf{F}^\top + \mathbf{Q} \end{align}

更新
状態の予測値から計算される観測値\mathbf{H}\bar{\mathbf{x}}と,実際に得られた観測値\mathbf{z}_tを比較して,状態の予測値\mathbf{x}_tと共分散行列\mathbf{P}_tを修正します(すなわち, 事後分布を計算します).

\begin{align} \mathbf{y}_t &= \mathbf{z}_t - \mathbf{H} \bar{\mathbf{x}}_t \\ \mathbf{K}_t &= \bar{\mathbf{P}}_t \mathbf{H}^\top (\mathbf{H} \bar{\mathbf{P}}_t \mathbf{H}^\top + \mathbf{R})^{-1} \\ \mathbf{x}_t &= \bar{\mathbf{x}_t} + \mathbf{K}_t \mathbf{y}_t \\ \mathbf{P}_t &= (\mathbf{I} - \mathbf{K}_t \mathbf{H}) \bar{\mathbf{P}}_t \end{align}

\mathbf{K}_tはカルマンゲインと呼ばれ,観測値\mathbf{z}_tに基づいてどの程度予測値\bar{\mathbf{x}}_tを修正するかを決定する.観測誤差共分散行列\mathbf{R}が小さければ(i.e., 観測値のノイズが小さい)\mathbf{z}_tを信用して強めに修正します(逆も然り).

手法

概要

オプトインカメラでは,撮影への同意(オプトイン)を得た人物にタグデバイスを携帯してもらい,環境に設置したカメラとアンカーデバイスを用いて,その人物だけを映した映像(オプトイン映像)を記録します.

オプトインカメラのシステム概要
オプトインカメラのシステム概要

以下の手順でオプトイン映像をつくります.

  1. UWB測位によるタグデバイスの追跡
  2. 映像からの人物追跡
  3. タグデバイスと人物の軌跡のマッチング
  4. 隠蔽処理

以降では,これらの手順を詳しく解説します.

1. タグデバイスの追跡

オプトインカメラの実装ではNXP社製のUWBチップを使った評価ボートを使用しました.

ToFとAoAを計測可能な2BPをアンカーデバイスとして環境に設置し,ボタン電池で動作する2DKをオプトインする人物に携帯させます.Two Way Ranging (TWR) によって,アンカーデバイスに対するタグデバイスの相対位置が,極座標形式(すなわち,距離,方位角,仰角)で得られます.さらに,アンカーデバイスの世界座標系[1]に基づく座標から,タグデバイスの座標を計算することが可能です.

ただし,UWB信号にはノイズが含まれるため,カルマンフィルタを用いてタグデバイスの位置推定を行います.カルマンフィルタの状態は,以下のように定義されます.

\mathbf{s} = (x, v_x, y, v_y, z)^\top

(x, y, z)は座標を表し,(v_x, v_y)はxy平面内の速度を示します.タグデバイスは首からかけたり,ポケットに入れて携帯することを想定しているため,zは定数とみなし,その変動はプロセスノイズに吸収させます.プロセスモデル \mathbf{s}_t = f(\mathbf{s}_{t-1}) には,運動学に基づく線形モデルを採用しています.

\mathbf{s}_t = \begin{bmatrix} 1 & \Delta t & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 & 0 \\ 0 & 0 & 1 & \Delta t & 0 \\ 0 & 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 0 & 1 \\ \end{bmatrix} \mathbf{s}_{t-1}

観測モデル\mathbf{z}_t = h(\mathbf{s}_t)は,世界座標系からアンカーデバイスを中心とした極座標を計算する関数です.具体的には以下のような計算をします.

\begin{align} \mathbf{p}_\text{anchor} &= \mathbf{R}_\text{cam}\ \mathbf{p}_\text{world} + \mathbf{t}_\text{cam} \\ \mathbf{z}_t &= f_{c \to p}(\mathbf{p}_\text{anchor}) \end{align}

\mathbf{R}_\text{cam}\mathbf{t}_\text{cam}は,世界座標系とアンカーの局所座標系を結ぶ回転行列および並進ベクトルを表します.関数 f_{c \to p}(\cdot) は,直交座標系から極座標系への変換を行う関数です.この観測関数は非線形であるため,無香料カルマンフィルタを使います.

プロセスノイズ行列 \mathbf{Q} は,人の歩行速度をもとに経験的に決定し,観測誤差行列 \mathbf{R} は,後述するキャリブレーションプロセスを通じて決定します.オプトインカメラの実装にはfilterpyを使いました.

2. 人物の追跡

まず,物体検出モデルを用いて人物を検出し,その結果をマルチオブジェクトトラッキング (MOT) アルゴリズムに入力することで,映像内のすべての人物に対するピクセル空間上の軌跡を取得します.次に,その軌跡を世界座標系へと投影します.

人物検出には,PINTO_model_zooの450番目のモデルであるYOLOv9-Wholebody-with-Wheelchairを使いました.MOTには,motpyというライブラリを使用しました.

ピクセル空間上の軌跡を世界座標系へ投影するにあたっては,奥行き情報が必要になります.そこで,頭部の幅と頭部のバウンディングボックスの幅を比較する手法を用いました.人間の頭部の幅が概ね一定であると仮定すると,頭部の奥行き d は,頭部の実際の幅 w_\text{real} と頭部バウンディングボックスの幅 w_\text{box} を用いて,以下のように計算できます.

d = f_{x} \frac{w_\text{real}}{w_\text{box}}

f_{x}はカメラの水平方向の焦点距離です.頭部の幅w_\text{real}は後述のキャリブレーションで求めます.カメラの外部パラメタ[2]と奥行きdを使って,ピクセル空間上の軌跡を世界座標系に投影します.

3. タグデバイスと人物の軌跡のマッチング

タグの軌跡の集合 {\mathcal{T}_i^\text{UWB}} と人物の軌跡の集合 {\mathcal{T}_j^\text{cam}} の要素間で,軌跡の距離に基づくマッチングを行い,映像中の人物とタグデバイスを対応付けます.ただし,motpy によるトラッキングは一定の頻度で失敗する可能性がある点に留意する必要があります.特に,同一人物であるにもかかわらずトラッキングが途切れることで,複数のトラッキングIDが付与されるケースが頻繁に発生します.そこで,次のような割当問題として定式化し,線形ソルバーを用いて解を求めます.

まず,次のような割当行列 X = (x_{ij}) を導入します.

x_{ij} = \left\{ \begin{array}{ll} 1 & (\mathcal{T}_j^\text{cam} \sim \mathcal{T}_i^\text{UWB}) \\ 0 & (\mathcal{T}_j^\text{cam} \nsim \mathcal{T}_i^\text{UWB}) \end{array} \right.

すなわち,軌跡ijが紐づくならば1,そうでなければ0になる変数です.その上で,次のような定式化を行います.

\begin{align} & \underset{X}{\max} & & \sum_{ij} \frac{1}{c_{ij}}\,x_{ij} \\ & \text{s.t.} & & \sum_i x_{ij} \leq 1 \\ & & & x_{ij} + x_{ij'} \leq 1 \ \ \text{if}\ \ \text{duration}(T_j \cap T_{j'}) > s_\text{slack} \\ & & & x_{ij} = 0 \ \ \text{if}\ \ c_{ij} > c_\text{threshold}. \end{align}

軌跡 ij が紐づく場合のコスト c_{ij} が小さいほど,マッチングしやすくなります.ただし,同一のタグデバイスに同時に複数の人物が紐づくのは妥当ではないため,これを防ぐための制約を加えています.また,c_{ij} が閾値以上になった場合は,マッチングしないような制約も導入しています.c_{ij} は,以下のように定義されます.

c_{ij} = \frac{1}{|T_i \cap T_j / T_\text{uc}|} \sum_{t \in T_i \cap T_j / T_\text{uc}} \mathrm{D}(\mathbf{p}_t^{i}, \mathbf{p}_t^{j})

T_iT_j はそれぞれ軌跡 ij の生存期間を表し,T_\text{uc} はタグデバイスの位置の不確実性が閾値以上になった期間を示します.\mathrm{D}(\mathbf{p}_t^{i}, \mathbf{p}_t^{j}) は,時刻 t におけるタグデバイスと人物の距離を表します.タグデバイスの位置は,カルマンフィルタによってガウス分布として推定されるため,その共分散行列を利用したマハラノビス距離を採用します.この問題を線形ソルバーに解かせることで,映像中の人物とタグデバイスの対応を得ることができます.

4. 隠蔽処理

前述のマッチングにより,各時刻において,映像内のどの人物がどのタグデバイスを持っているかが特定できるため,その情報に基づいてオプトインしていない人物を隠蔽します.単純な方法としては,タグデバイスを持つ人物のバウンディングボックスを切り出し,誰も映っていない背景画像に重ね合わせる手法があります.ただし,この方法ではバウンディングボックスの境界が目立ち,不自然なオプトイン映像になりがちです.より自然なオプトイン映像を作成するためには,計算コストが増加するものの,オプトインしている人物のセグメンテーションマスクを使用する方法が有効です.この方法により,人物の形状に沿った自然な隠蔽が可能になります.

バウンディングボックスベースの隠蔽処理
バウンディングボックスを使った単純な隠蔽処理

性能を上げるための自動キャリブレーション

UWB信号が人間に遮蔽されると,測位精度が低下する(NLoS問題)ため,マッチングが失敗するケースが発生します.さらに,アンカーデバイスの設置パラメータや頭部の幅といった要素を事前に決定する必要があります.これらの課題を解決するために,自動キャリブレーションの仕組みを開発しました.1人の人物がタグデバイスを携帯して撮影エリア内を動き回り,キャリブレーションデータを収集します.そのデータを利用して,以下のパラメータを推定します.

  1. 世界座標系におけるアンカーデバイスの位置と向き,及び,頭部の幅
  2. NLoS判定器
  3. 観測誤差行列R_\text{LoS}R_\text{NLoS}

キャリブレーションデータのサンプル
キャリブレーションデータのサンプル

世界座標系におけるアンカーデバイスの位置と向き,及び,頭部の幅
1では,キャリブレーションデータの各時刻におけるタグデバイスの推定位置と頭部の位置が近づくように設置パラメタを最適化します.ただし,NLoSの瞬間のデータを信じると誤ったパラメタになるので,RANSACと呼ばれる外れ値に強いパラメタ推定手法を使います.

NLoS判定器
2では,1で副次的に得られる外れ値のラベルをNLoSとみなし,CIRやSNRなどの受信信号に関する情報からNLoSかどうかを判定するモデルを学習します.LightGBMを使いました.

観測誤差行列R_\text{LoS}R_\text{NLoS}
3では,カルマンフィルタの更新ステップで使う観測誤差行列を求めます.まず,カルマンフィルタを若干改造します.更新ステップの実行時に,UWBの観測信号がNLoSかどうかを判定し,それに応じて観測誤差行列をR_\text{LoS}R_\text{NLoS}とで切り替えます.そして,キャリブレーションデータにおいて,常にタグデバイスの推定位置と人物の位置のマハラノビス距離を一定値以下に保ちつつ,R_\text{LoS}R_\text{NLoS}をブラックボックス最適化で最小化します.CMA-ESというアルゴリズムを使いました.

結果

以下が,19人の中で1人だけタグを持っている状況での実行結果です.
実験結果

他のサンプルもこちらで見られます.

終わりに

オプトインカメラの仕組みについて解説しました.さまざまな方々にデモをお見せする機会をいただいているのですが,そのたびに皆さんが驚かれるので,つい得意げな気持ちになってしまいます(笑).このオプトインカメラが,個人の行動計測を促進し,適切なマーケティングへの活用につながるきっかけになればいいなと思っています.

脚注
  1. 施設の任意の場所を原点とする直交座標系.便宜上,床をz=0とする ↩︎

  2. OpenCVのArUcoマーカを使ったキャリブレーションを利用します. ↩︎

Discussion