VMCとOculusMRCで合成 ~カメラ位置解決編~

要約

(2021年4月:(おそらくOculus側のソフトウェアアップデートにより)Oculusのソフトウェアを立ち上げながらSteamVR側でHMDのトラッキングをすることができなくなってしまったようです。残念ながら、ここに書いていあるやり方は通用しなくなってしまいました)Oculus Mixed Reality Captureのカメラ位置の設定できるようになった。


以下、私的な試行錯誤なので、なにかあれば私@skm58によろしくお願いします。(なんとなくふと気になってしまい追記しました 2019/07/02)


前回のあらすじ

Virtual Motion CaptureとOculus Mixed Reality Captureでクロマキー合成できるようになったけど、カメラ位置合わせができない。

(しつこいですが)注意

前回、VMC+MRCを試して環境が壊れてしまった例があったそうですので、実行する場合はご注意ください。

この記事書いてる人も、自分が何をしているのかよく理解していません。

やったこと

できるようになったこと

VMCで出力したexternalcamera.cfgをもとにして、カメラ位置をOculus MRCに反映することができる。

カメラ位置と画角を変えてテストした。

正面で画角が大きい場合

カメラ位置フリーで設定、画角小さめの場合

ちゃんとできてるように見える。

あまり手を伸ばすと手首が離れたりしてちょっと怖い。これはコントローラー入力ができなくなるのをごまかすため、手に少し細工をしているせい。このあたりは下の方の「LIVでやる時との違い」で触れてます。

VMC + MRC合成作業流れ

スクリプト

extcam2camcalib

extcam2camcalib :恥ずかしながら公開

template.xml

スクリプトと同じディレクトリにtemplate.xmlというファイルを置く必要がある(一緒にgithubにおいてあるやつ)。これを雛形にして値が出力される。

このファイルの最初の方にカメラの名前(?)を書く場所があるが、自分の場合

<camera_name>"0411&amp;pid_0260&amp;mi_00#7&amp;17e718de&amp;"</camera_name>

と書いてあった。しかし、ここを空欄

<camera_name>""</camera_name>

にしても手元では動いたので、githubに置いてあるやつは空欄にしてある。この辺りまったく手探りでわからない。

LIVでやる時との違い

コントローラーの入力ができなくなる

これがあるので、いまのところLIVでやれる場合はLIVでやった方が良い。

具体的には指と表情の操作ができなくなるので、VMCの良さを一部損ねてしまう。けど、幸いなことにトラッキングはできる。たぶんリップシンクも動いたはず。

仕組みを理解してないので想像だが、Oculusのゲームを起動するとSteamVRが裏側に行ってしまうようだ。結果、SteamVR側で動いてる(とおもわれる)VMCのコントローラー操作ができなくなるらしい。

今回は、もともと手のモデルが出てくるソフトを使ってるので、アバターの手の部分を透明にして隠し、擬似的に指を動かせる手があるようにみせかけている。手を伸ばしすぎると手首が離れるし、たまに袖との前後関係もおかしくなるが、自分はこのやりかたで満足した。

HMDのほうに合成映像を出せない

なにかツールを使ったらできるのかもしれないけど、今のところパッとはできてない。

数値の対応関係のまとめ

試作スクリプトでの座標・回転などの対応表

試行錯誤で決めたので謎が多い。たとえばカメラのy座標に謎の定数1.65がついてるが、これは「手の位置の具合からして1.65がベストかな?」とかいう感じで適当に決めた。なのでセンサーの設定とかアバターのサイズとか、ゲームによって変わってしまうかもしれない。


以下備忘録です

まとめ画像と重複するが、xmlの中身を読んだ過程の備忘録。

VMCで出力されるexternalcamera.cfgをcfg、MRC(CameraTool)に入力するcameracalibration.xmlをxmlと呼ぶことにする。

cfgでのカメラ座標(x,y,z)とxmlでの(X,Y,Z)の関係

<translation type_id="opencv-matrix">

の部分

どれがどの座標か推測しやすいので、謎の定数を除けば、比較的簡単にわかった。

fovとcamera matrixの関係

<camera_matrix type_id="opencv-matrix">

の部分

fovとかカメラ行列って何?というところからスタート・・・

カメラ行列mは3x3の行列で、

行と列が逆かもしれない。いずれにしても、今回のxmlの中では、fx 0 cx 0 fy cy 0 0 1 と並べて書く。

行列の定義などは以下を参照した。

cxとcyは、画像の中心になるようにとる。仮に1280 x 960のサイズだったら, cx=640 cy=480とする。これだとぴったり中心じゃない気もするけど、細かいことは気にしていない。

fxとfyは、それぞれピクセル単位での焦点距離。ピンホールカメラとして考える、らしい。fxと水平画角、fyと垂直画角が関係するらしい。以下の文書などを参考にした。

Unityのドキュメントによれば「This is the vertical field of view」らしいので、垂直画角だけ考えることにする。

画像の高さだけ考え、垂直画角をfov_yとすると

(H/2)/fy = tan(fov_y/2)

なので、

fy = H/(2*tan(fov_y/2))

fx = fy

で計算。角度は弧度法の値なので、ラジアンに直すか弧度法用の関数をつかう。

回転

<rotation type_id="opencv-matrix">

の部分

ここが一番難しかった。

正体不明の4変数 -> 四元数

実際にキャリブレーションしたときのxmlを読んで、数値をなんとなく二乗して全部足したら約1.0だった -> もしかして四元数・・・?

係数の順番も謎なんだけど、たぶん real i j k か i j k real だと推測して両方試した。

回転行列の角度の正の方向が不明 -> 適当に決めた

試行錯誤で、全部の軸について rx’ = 360 - rx などとするとうまく一致することを確認した。たぶん座標系が反転してるのとつじつまがあう。

回転行列の掛け算の順番が不明 -> 適当に決めた

Unityだと回転行列の作用順番はYXZかZXYらしいので、その2つに絞った。けど今回のやつにはあまり関係なかったかもしれない。とりあえず全パターン試さずに済んだのは運がよかった。

感想

メモ

ソフト

Tweet