#はじめに
岐阜県にあるIAMASという学校に通っている @minoge1001 と申します。2年連続のアドカレ参加です(昨年の記事はこちら)。
10月3日に行われたNxPC.Live vol.46 X 1/2というライブで、Azure Kinectを2台用いて以下のような演出を行いました。今回の記事では、2台のAzure Kinectをどのように組み合わせて使ったのかというセッティング周りについて紹介します。
Realtime audio visual performance 01 (Saxophone: @k_saxofocus)#TouchDesigner #GLSL #AzureKinect #pointcloud #creativecoding pic.twitter.com/HIZ7aYNDeK
— Yugo Minomo (@minoge1001) October 10, 2020
Realtime audio visual performance 02 (Saxophone: @k_saxofocus)#TouchDesigner #GLSL #AzureKinect #pointcloud #creativecoding pic.twitter.com/Dlj0wo3LkF
— Yugo Minomo (@minoge1001) October 10, 2020
Realtime audio visual performance 03 (Saxophone: @k_saxofocus)#TouchDesigner #GLSL #AzureKinect #pointcloud #creativecoding pic.twitter.com/7tsjINWAoF
— Yugo Minomo (@minoge1001) October 11, 2020
Realtime audio visual performance 04 (Saxophone: @k_saxofocus)#TouchDesigner #GLSL #AzureKinect #pointcloud #creativecoding pic.twitter.com/HYBtRPg4e5
— Yugo Minomo (@minoge1001) October 11, 2020
Realtime audio visual performance 05 (Saxophone: @k_saxofocus)#TouchDesigner #GLSL #AzureKinect #pointcloud #creativecoding pic.twitter.com/UhGDk1bgfY
— Yugo Minomo (@minoge1001) October 11, 2020
#動機
動機は単純で「2台のAzure Kinectで挟み込んで撮影した時にVolumetric的な演出がどのくらいできるのか試したい」ということでした。ですので、側面方向が上手くキャプチャできない、オクルージョンに弱い、そもそも完璧な人物像は取れない、等の問題は織り込み済みで進めました。ざっくり言うと、Azure Kinect 2台からRGB/PointCloudの2種類の画像を1台のPCに取り込んで、それぞれ種類ごとに1枚の画像にまとめた上でInstancingなどで演出をつけるという流れです。
#配置の検討
今回のライブでは、サクソフォン奏者である@k_saxofocusさんとのコラボなので、まずは全身(約165cm)をキャプチャするために必要な空間の大きさとAzure Kinectの配置を検討しました。
今回の条件ではキャプチャ対象である演奏者の位置はほとんど変わらないので、Kinect Azure TOP
のDepth Mode
はNarrow FOV - Unbinned(640x576)
としました。演奏中の動作としては
- 下手側のテーブル上にあるMacbook Proを操作する
- 演奏中に体が揺れる(主に前後方向)
の2種類がありましたが、映像のアスペクト比的には後者(縦方向)の方が厳しいので、前後50cm程度動いても頭と足が切れないようなラインを狙いました。Azure KinectはRGBカメラ・Depthカメラともに画角が光軸から上下対称なので、理論的には身長の半分の高さに設置するのが(解像度的には)ベストですが、生カメラとしてテイクする演出も考えられたので身長の半分より少し高めに設定しています。
なお、2台のカメラはなるべく水平にした上で光軸や高さも極力一致させるのが理想ですが、微調整はTouchDesigner上で行うので、そこまでシビアに頑張らなくても大丈夫です。結果、以下のような配置になりました。
以降、演者正面側のAzure KinectをAK①、背面側をAK②と呼ぶことにします。今回のライブは無観客配信だったので、VJ(私)はAK①の真後ろにメインPCを置いてオペレーションしています。
#データの伝送
配置が決まったところで、遠く離れたAK②からのデータをメインPCに取り込むための通信路を考えます。ケーブル長は迂回や立ち上げ等を考えると8m以上は必要なので、USBで伸ばそうとするとアクティブ延長ケーブルが必要となります(ホロラボの中村さんの記事が非常に参考になります)。…が、個人で購入するには少々お高く、そもそも納期がイベントに間に合わないという事情もあり、USBでの延長は諦めて同じネットワーク内にサブPCを用意し、それを経由させてギガビット(1Gbps)LANで伸ばすことにしました。
ところで、PointCloud画像は非圧縮(もしくは可逆圧縮)で伝送する必要があります。通常よく使われる非可逆圧縮は人間の目では変化が捉えづらい色差成分を間引いたり高周波成分のデータを削ったりすることでサイズを小さくしますが、PointCloud画像でこれをやってしまうと(映像としては問題なく見えても)位置情報が破綻します。ということで、NDI Out/In TOP
は使えず、必然的に非圧縮で伝送できる**Touch Out/In TOP
**を使うことになります。
Kinect Azure TOP
のCamera FPS
は30
にします。PointCloud画像は32bit RGB
なので、出力解像度(Color Resolution
)を一番低い1280×720
にしてもデータレートは**(32×3)×(1280×720)×30=約2.654Gbpsとなり、全くギガビットのLANを通りません。そこで、Resolution TOP
で半分の解像度(640×360
)にします。こうすると、データ量が1/4の約660Mbps**になるので、RGB映像を圧縮すれば1Gbpsに納まりそうです。RGB画像はTouch Out TOP
でHAP Q
を指定します。こうして、無事にLANで伝送することができました。なお、Resolution TOPのInput Smoothness
をNearest Pixel
に変更するのを忘れずに!
以下の図がAK②から入力を受けてメインのPCにデータを転送するサブPCのネットワークです。
なお、本題から逸れますが、このようなケースでは
- LANケーブルのカテゴリーがCAT 5e以上であることをちゃんと確認する
- ネットワークインタフェースの設定をオートネゴシエーションではなく手動で1Gbps/全二重にする
などの細やかな気遣いをすることで、無用なトラブルを避けることができます。
#メインPCのネットワーク
メインPCのネットワークを示します。なお、もう一度同じセッティングをする時間がありませんでしたので、Azure Kinectからの入力は適当です。
以降、特に断りがない限り、TOPのCommon
タブのInput Smoothness
はNearest Pixel
に統一してください。
##入力&解像度変更
直接接続しているAK①の映像をKinect Azure TOP
とKinect Azure Select TOP
で取得し、Resolution TOP
を繋げてAK②からの入力解像度(640×360
)に合わせます。AK②からの入力はTouch In TOP
で受け取ります。その際、Network Port
がサブPCのTouch Out TOP
の値と一致している必要があります。
##遅延調整①
2台のAzure KinectのPointCloud画像、RGB画像どうしのタイミングを合わせます。直接接続されているAK①の方が早いので、AK①側のPointCloud/RGB画像にそれぞれCache TOP
を接続します。ここでは、誰かに被写体に入ってもらって、頭上でパチパチと手を鳴らしてもらう等のアクションをしてもらうとスムーズに作業できます。なお、この段階ではPointCloud画像全体とRGB画像全体のタイミングは合っていませんので、最終段(遅延調整②)で合わせます。なお。今回の自分のセッティングでは、PointCloud画像を-18 Fr
、RGB画像を-4 Fr
とすることでタイミングが合いました。
##位置調整
被写体がワールド座標系の原点にくるように、Palette
内のPointClouds
>pointTransform
を用いてPointCloudの位置を調節します。撮影されるPointCloud画像はカメラの位置が原点で方向が+z軸となるので、上記の配置の場合には、z軸方向におおよそ-2.125
、y軸方向におおよそ+1.02
だけ平行移動させることで被写体の足元が原点に移動することになります(TouchDesignerの単位系はメートル)。その上で、どちらかの画像をy軸周りに180°回転させることで、被写体を前後から挟み込むような位置関係となります。また、セッティングの段階でAzure Kinect自体が正対していなかったり(パン方向のずれ)水平ではなかったり(チルト/ロール方向のずれ)した場合もここで修正します。
この工程は、次の画像統合のLayout TOP
を繋げてから行うとやりやすいです。Layout TOP
をActive
にして右クリックからView as Points
を選ぶことで点群表示にできます。先にひとつのTOPに纏めてしまうことで、PointCloud画像がきれいに繋がる位置を探ることができます。なお、ここでの被写体は動いている必要はないので、箱馬を重ねるなどある程度上背のあるダミーがあればOKです。
##画像統合
PointCloud画像、RGB画像どうしをそれぞれLayout TOPで1枚の画像にします。それぞれ640×360
の2つの画像が入力となるので、縦に繋げて1つの640×720
の画像を作ります。
タブ | パラメータ | 値 |
---|---|---|
Layout | Align | Top to Bottom |
Common | Output Resolution | Custom Resolution |
Common | Resolution | 640, 720 |
Common | Output Aspect | Resolution |
PointCloudを格納したTOPをまとめるツールとしてPalette
内のPointClouds
>pointMerge
がありますが、ここでは使うことはできません。RGB画像側と全く同じ結合の仕方をさせることで、同じ位置にある画素に格納された点群の位置情報と色情報が一致するためです。
##不要な点群の削除
今回の記事では触れませんが、人物領域のみを抽出するためにPointCloud画像に対してRGB Key TOP
を用いて不要な領域を削除しています。このあたりは、TDSWのVol.32で詳しく解説されているので、ご参照ください。
##遅延調整②
それぞれ1つの画像にまとまったPointCloud画像とRGB画像のタイミングを合わせます。早いRGB画像側にCache TOP
を入れます。今回の自分のセッティングでは-15 Fr
でタイミングが合いました。
##Instancing用TOP
最終的に、点群の位置情報を持ったTOPと色情報を持ったTOPが出来たので、Geometry COMPを使ってインスタンシングを行うことで、リアルタイムにVolumetricっぽいポイントクラウドを扱えるようになりました。
但し、動機で述べたように、側面のデータは取れていません。
#まとめ
今回の記事では、Azure Kinectを2台使って簡単なVolumetric的表現を行う方法について紹介しました。完全な人物像を取得することはできませんが、演出によっては低コストで何か面白いことができるかもしれません。
#補足
##ポイントクラウドが上手く表示されない場合
PointCloudに錐体状のノイズが乗るときは、解像度が変わる系のTOPでInput Smoothness
がNearest Pixel
以外になっています。また、xyzの範囲が0~1にクランプされていたり、平面状や直線状に潰れされているときは、Pixel Format
が正しくありません。ビット深度は16 bit
以上にし、チャンネルはRGBA
にしましょう(Instansing時のActive
パラメータにAチャンネルを指定すると、何かと便利です)。
##他のカメラについて
実際には、Azure Kinectの他に、演者正面にミラーレス一眼(バストショット用)と、演者から見て左上方にwebカメラ(全身俯瞰用)の2台のカメラを使っています。これらのカメラとの位置合わせ作業は、ポイントクラウド表示した被写体と実写映像がうまく重ね合わさるように地道に行います(かなり大変です…)。
##Azure Kinectの外部同期機能
Azure Kinectには3.5mmオーディオケーブルを用いて同期させる仕組みがあり、Kinect Azure TOP
でもサポートされていますが、今回のシステムでは時間的問題もあって使用しておりません。なお、仮に使用したとしても、今回の構成では何らか同じような調整が必要だと思われます。
それでは、皆様良い年末を!