Tutti Lab

元シリコンバレー在住のおっさん技術者、モバイルVRアプリ開発に挑戦中

Cardboardで360度立体視動画ビューワーを作る(3)

はじめに

前回は、左右両眼用のThetaSのビデオ(RICOH THETA UVC BlendeによりEquirectangular形式に変換されたもの)を縦につなぎあわせ、OBSでHLS形式のライブストリーミングを生成、nginxで配信、Cardboard側で閲覧する、というシステムを作りました。しかし、一応動いたものの、遅延が激しく・フレームレートも出ない、との状況であり、実用には程遠い状況です。
今回は「リアルタイム性」を重視し、一度Cardboardを離れて、Oculus Riftで、左右両眼用ThetaSを利用した360度立体視を行ってみます。

UnityをOculus Riftに対応させる

現状Oculus Riftに対応しているUnityは、バージョン5.3.4p1及び、5.4βです。今回は5.3.4p1をインストールしました。5.3.4p1はこちらから入手できます。
次に、Oculus開発者サイトより、OVRPlugin for Unity 5をダウンロードします。ダウンロード後、C:\Program Files\Unity\Editor\Data\VR\oculusの内容を全削除した後、OVRPlugin_Unity5_1.3.0.zipを解凍したもので置き換えます。

Theta SのFish Eye形式動画をEquirectanguler形式に変換

前回記載した通り、RICOH THETA UVC Blenderを利用すれば、Equirectanguler形式で直接動画を取得できるため、変換処理等は不要となります。ところが、当方環境の問題なのか、Windows版の制限なのか、Theta Sを2台接続(両方ともTHETA UVC Registerで登録)した場合、いずれか一方のみのRICOH THETA UVC Blenderしか利用できません。再接続、再登録を何度か試みましたがうまくいかず。このため、Theta Shader Packを利用して、Unity側にて形式変換をすることにしました。
上記サイトよりThetaShaderPack_20150926.zipをダウンロード・展開し、適当なフォルダへ格納してください。次に、Assetsを右クリック→Import Package→Custom Packageを選び、ここで展開したThetaShaderPack.unitypackageをインポートします。
次にWebカメラの映像をテクスチャとして利用すべく、簡単なスクリプトを用意します(こちらを参考にしました)。

gistc83f1ae3dfa5c5c3f19f7ac346e3d48c
合わせて前回ご紹介したsphere100.fbxを用意します。Assets内の適当なフォルダに放り込んだ上で、2つこれをHierarchyへドラッグ&ドロップ、それぞれの名前をSphere100_L, Sphere100_Rとします。
インスペクタにて、それぞれ以下のように設定します。なお、camIndexはそれぞれ、左右用ThetaのFisheye形式UVCを指定してください(当方の環境では0及び1でした)。
f:id:tuti107:20160504123929p:plainf:id:tuti107:20160504123940p:plain
マテリアルには、上記インポートしたTheta Shader Packに含まれるThetaRealtimeEquirectanguler (Both).matを指定ください。
また、LayerをぞれぞれLEFT、RIGHTとしてください。
次に、左右両眼用のカメラを作成し、それぞれSphere100_L, Sphere100_Rのみ見えるよう設定します。Hierarchyにて右クリック→Cameraを二度実施し、作成したカメラをそれぞれCameraL,CameraRとしてください。CameraLは左目用なので、Culling MaskからRIGHTを外してください。またTarget EyeはLeftとしてください。同様に、CameraRはCulling MaskからLEFTを外し、Target EyeをRightとしてください。
最後に、File→Build Setting→Player Setting→Other Settingにて、Virtual Reality Supportedをオンとします。OculusはUnityにてネイティブでサポートされているため、CardboardのときのようなSDKのインポートや各種設定は不要、これだけでOculusで利用可能となります。
f:id:tuti107:20160504131534p:plain

まとめ

今回はOculusを使って、左右両眼用Thetaの入力画像をUnityで形式変換し表示するアプリを作成しました。またVirtual Reality Supportedをオンとして、本アプリをVR対応としました。前回のように、ストリーミング変換やライブ配信をやっていないこともあり、Thetaで撮影した映像をリアルタイムで楽しむことが可能です。またCardboardと比較して高画質・首の動きにすいつくようなヘッドポジショニングであり、非常に心地よいです。
ちなみに、詳細説明は省略しますが、前回同様Equirectanguler形式の左右映像を縦に並べ、OBSでエンコードし、nginxへアップロード・配信するアプリも作成してみました。前回のMACの場合のようにコマ落ちは発生しませんでした(NVidiaのH.264エンコーダのおかげかと思います。さすがGeForce970)。ただし相変わらず20秒程度の遅延は発生します。リアルタイムは難しいようです。

Oculusのインストールにはまる

待ちに待ったOculusがようやくきました。合わせて購入したOculusPC(ASUS G11CD)、起動するとOculus Downloadのアイコンが。
f:id:tuti107:20160501141241p:plain
Oculus Readyの認証をとっているPCということもあり、コンシュマー向け製品として簡単にインストールできるようになっているのだろう、とこの段階では思っておりました。まさかセットアップに6時間以上かかることになるとは。

Restart Computer

上記のアイコンからインストール用のアプリをダウンロード、すると800MB程度のデータのダウンロードが始まります。そして、ダウンロードが完了すると、以下が表示されます。
f:id:tuti107:20160501141521p:plain
エラーが発生した、という事実しかわかりません。とにかくリブートしろとのことなので、Windowsを再起動、その後再挑戦。また800MBのデータダウンロードがはじまります(キャッシュしてくれればいいのに)。そして、上記と同じエラーが表示されます。
何度か再起動→再挑戦を繰り返すも、結果は変わらず。インターネットでの情報さがしを始めました。
まだ発売して間もないこともあり、あまり情報がない状況なのですが、このページを発見。まずは、GeForceのドライバを最新にせよ、と。忘れてました。。ドライバを更新し、再挑戦。しかし同じエラー。
先ほどのページを読み進めると、
f:id:tuti107:20160501142643p:plain
レジストリをいじれ、とのこと。これコンシュマー用ですよね?
しかし上記の説明の通りにレジストリのプロパティーを表示しても「Reorder」というボタンが発見できません。だめならレジストリーキーを消してみて、との記述もあるため、削除して再挑戦を試みたものの、結果は同じ。毎回800MBのデータダウンロードが入るため、ここまでですでに4時間経過、もう諦めようかと考えていたところで重要な情報が。上記のページ内から参照されているこちらに、エラーログが「%LOCALAPPDATA%\Oculus\OculusSetup.log」に保存されており、そのエラー次第でいろいろ対策が必要な旨の記載がありました。さっそくログを調べてみると私の場合は
C:\Program Files\Oculus\Support\oculus-librarian\OVRLibrarian.exe exited with code 7 (failure).
でした。残念ならが本ページ内には対策の記載なし。そこで、上記エラーをキーワードとして調べてみると、こちらのページが見つかりました。なにやら、ウィンドウズの再インストールで治った等の不安を掻き立てる書き込みがある中、ウィルススキャンソフトをアンインストールすると解決した、との記載が。そこで、マカフィーセキュリティセンターをアンインストールし、再挑戦。ようやく問題解決!その後はすんなりインストールができました!

絶縁シールが引き抜けない

これでようやく、と思っていたところで最後の罠が。ソフトのインストール後、ハードウェアの設定を順次行うのですが、
f:id:tuti107:20160501145225j:plain
このコントローラの電池の絶縁シールが異様に固く、ペンチで引っ張っても引き抜けず、しまいには破けてしまい引き抜きが不可能になってしまいました。仕方なく絶縁シールが出ている口の部分にマイナスドライバーを入れて背面をこじ開けて、絶縁シールを引き抜きました(それでも固く、引き抜いたら電池も一緒に吹っ飛んでいきました)。僕のものだけ、たまたまなのでしょうか?

苦闘6時間

セットアップが終わる頃にはもう夜中の2時。アプリケーションを試す気力もなく、セットアップだけで終了、そのまま就寝しました。
まだ商品出始め、ということで、トラブルシューティングのノウハウもインターネット上に充分溜まっていない状況です。僕の上記のエラー以外にも、いろいろパターンがあるようです。今後Oculusを購入し、インストールする方は、ログから問題を特定し最短でトラブルシューティングを行うよう、ご留意頂ければ、と思います。

Lucid Cam

今日は地元で開催されたVRステレオカメラのミートアップに参加しました。このカメラLucidCamは、180度撮影可能なカメラを2機搭載しており、ステレオ4K動画(秒60フレーム)を撮影可能です。単純比較はできませんが、同価格帯の他社機よりハイスペックかと思います。
f:id:tuti107:20160427143255j:plain
左右カメラで撮影された映像は4KFisheye動画を横に並べた形式で保存され、専用のスマホ側アプリにて立体視360度動画として視聴可能です(ただし、本カメラは前方180度しか撮影できないので、後ろ180度は前方180度のコピーのようでした)。デモ映像の映像品質や立体感はなかなかのものでした。
本ミートアップでは、左右撮影映像のキャリブレーション技術について、詳細説明がありました。キャリブレーションが必要な歪みは3パターン(魚眼レンズによる歪み・センサー傾きによる歪み・左右カメラずれ)で、それらの検出方法と対処方法の概要について触れられました。
f:id:tuti107:20160427145224j:plain
値段は$399で、今年の12月に出荷予定とのことです。
気になる点は、ホームページにはビデオは2Kと書いてあるのですが、説明ではビデオ4K静止画8Kと言っていたはずなんだよなぁ・・(英語自信なし)

Magic Leapが少しずつ明らかになってきています

WIREDにて「謎のARデバイス」Magic Leapの特集がされています。これまでデバイスに関する情報はほぼ皆無でしたが、今回キーデバイス(だと思われる)について言及がありました。このレンズ(?)を通して現実世界を見ることで、その現実世界に様々な3DCG拡張情報が表示される、これだけだとHoloLens等と一緒ですが、これらのように「スクリーン投射」でCGを重畳するのではなく、別の方法で実現しているそうです。いったいどんな方法なのでしょうか?
f:id:tuti107:20160426133559p:plain
いずれにせよ、ARが本格普及する時代には物理的な「スクリーン」は意味のないものになり、平面・立体のCGを現実空間上に貼り付けて利用することになります。PCにディスプレイは不要、ウィンドウを空間に貼り付けて利用する。アプリ・UIは激変します。今はまだ、Magic Leapがいつ出てくるのか(本当に出てくるのかも含め)わかりませんが、Meta2は今年の秋に出てくることですし、真剣にAR世代のアプリ・サービスを考え始めないと、と思っています。

Cardboard向けバーチャルキーボードを作ってみる

はじめに

Google Cardboardには、二種類の入力手段が用意されております。一つはGaze、画面中央に対象物が来るように首を動かすと、ゲージが現れます。ゲージがいっぱいになるまでそのままの状態を保つことで、対象物へのアクセスが可能となります。もう一つは、同じく画面中央に対象物が来るように首を動かすと照準が現れるので、その状態でボタン( Google Cardboardの右上部分、カメラのシャッターボタンのようなもの)を押下、対象物にアクセスするというものです。
いずれも首を動かして対象物の方を向く、という、VRらしい方法を前提にしております。
今回は「対象物の方向に向いてボタンを押す」入力手段を利用して、バーチャルキーボードを作ってみます。果たして「対象物の方向に向いてボタンを押す」方法で、問題なく文字入力ができるのか?その課題についても考えてみます。
f:id:tuti107:20160424043555p:plain

スクリプトの用意

Unity Assetには、有料のバーチャルキーボードのアセットが幾つかあるようですが、今回はそれらを利用せず、一からスクラッチしてみます。
利用するのは、前回ご説明したiTween、64 Flat Game Icons、あとはGoogle Cardboardです。まずはそれぞれインポートします。
次にスクリプトを作成します。今回は以下の3つのスクリプトを作成しました。

gist7e6babd903b2492c47bac7e68f74dd00

キーボード用のオブジェクトを用意

次にシーン内のオブジェクトを配置していきます。
最初に、デフォルトで配置されているMain CameraとDirectional lightを消し、Cardboard Mainを代わりに配置します。この時自動的に作成されるCardboardは不必要なので消してしまいます。ここまでは前回までと同様です。
次にキーボードに貼り付けるキーを作成します。Hierarchyにて右クリック→3D Object→Cubeを選択、名前をKeyとします。さらにそのKey上で右クリック→3D Object→3D Textを選択、名前をTextとします。これでKey配下にTextがある状態になります。Keyには、インスペクタより以下の通り設定をします。
f:id:tuti107:20160422003943p:plain
上記で作成したスクリプトKey.csをコンポーネントとして追加しText Meshに、上記でKey配下に作成したTextのText Meshをドラッグ&ドロップします(インスペクタ内のコンポーネントをドラッグ&ドロップしてもう一方のインスペクタに設定する方法は、こちらのインスペクタで関連付けを参照ください)。
Event Triggerには、Pointer Click時にKey#Push()を呼び出すように設定ください(Event Triggerについてはこちらのスケルトンをクリック可能にするを参照ください)。ここまで出来ましたら、KeyをProjectの任意のフォルダへドラッグ&ドロップし、KeyをPrefab化します(prefabについてはこちらのスケルトンをPrefab化するを参照ください)。なお、KeyのPosition、Rotation、Scaleについては、Board.cs内で計算・設定されるため適当な値で良いです。
次にKey群を配置するボードを作成します。Hierarchyにてクリック→3D Object→Cubeを選択、名前をBoardとします。さらにBoard上で右クリック→3D Object→Cubeを選択、名前をDisplayとします。さらに、そのBoard上で右クリック→3D Object→3D Textで、名前をTextとします。以上で、Board-Display-Textという構成のオブジェクトが作成されました。インスペクタでの設定は以下の通りです。
f:id:tuti107:20160422005047p:plain
上記で作成したスクリプトBoard.csをコンポーネントとして追加し、Key Prefabには上記でPrefab化したKeyを設定してください。Displayは上記で作成したDisplayをドラッグ&ドロップします。
f:id:tuti107:20160422005804p:plain
上記で作成したスクリプトDisplay.csをコンポーネントとして追加し、Textには、上記KeyのText同様、Dislay配下のTextのText Meshを設定します。

イベント処理

次にイベント処理用の設定を行います。まずHierarchyにて右クリック→Create Empty、名前をGazePointerとします。次にそのGamePointer上で右クリック→2D Object→Spriteを選択してください。そのSpriteのインスペクタにて、以下の通り、Transform/Spriteの設定を行います。Modifiers_Accuracyについては64x64のものを選択してください。
f:id:tuti107:20160422010339p:plain
次にHierarchyで右クリック→UI→Event Systemを選択、インスペクタよりGaze Input Moduleを追加し、以下の通り設定します。
f:id:tuti107:20160422010627p:plain
Cursorには、上記で作成したGamePointerをドラッグ&ドロップしてください。
最後に、CardboardMain/Head/MainCameraにPhysics Raycastを追加してください。
f:id:tuti107:20160422010842p:plain
これで完成です。

一応入力は出来るけど

f:id:tuti107:20160424043703p:plain
課題を列挙してみます。

  • 押したいキーの方を向き、そのキーを画面の中心(照準部)に合わせて、シャッターボタンを押す必要があるのですが、右下の方に配置されているキーを見ている時は、Displayに表示の「これまで入力した文字列」が見えません。
  • バーチャルキーボードの表示位置は、シーンの3D空間内となります。前回のライフを追加にてライフのハートをCardboard Main/Headに配置することで常に一定位置に表示する方法をご紹介しましたが、このような方法をとることができません。照準は常に画面中央なので、それぞれのキーに照準を当てることができなくなるためです(一つのキーしか押せません)。このため、アプリケーション毎にキーボードの表示位置を工夫する必要が出てきます。
  • 高速・長文・長時間の文字入力はかなり厳しいです。首も腕もかなり疲れます(想像していたよりは、かなり素早く入力できる印象でしたが)。

まずは今回、シンプルなバーチャルキーボードの実装をしてみましたが、まだこのままでは実用に耐えない印象です。ただし、工夫次第ではVRコンテンツで広く活用できるバーチャルキーボードへの進化も可能かな?と可能性は感じました。

Cardboardで360度立体視動画ビューワーを作る(2)

はじめに

前回は、EasyMovieTextureを使い、360度立体視動画ビューワーを開発しました。前回は、Assets/StreamingAssetsに360度立体視動画形式のmp4を直接配置して、これを視聴するという形でしたが、今回は二台のTheta Sより撮影した右目・左目用の360度画像をブロードキャストし、Cardboardにて視聴するところまで開発を進めます。
f:id:tuti107:20160420162743j:plain

Easy Movie Textureはライブストリーミングに対応しているのか?

まずは確認から。HLS形式のストリーミングを再生できるかどうか、テストしてみました。Media Player CtrlのStr File Nameに、適当なURL(http://..../**.m3u8)を指定し実行したところ、問題なく再生されました。Easy Movie Textureは、少なくともHLS形式のライブストリーミングに対応しているようです(他のプロトコルについては試しておりません。iOSへの配信を考慮するとHLS形式一択ですので)。
なお、「Http://..../**.mp4」形式の動画も問題なく再生されました。ご参考まで。

Theta Sの360度動画をPCへ取り込む

Theta Sには、USB/HDMIでPCに接続して、PC側でライブストリーミング表示する機能が搭載されています。USBなら1280x720 15fpsで取り込みが可能です。ただ、形式はDual Fisheye形式であり、このままでは前回開発したアプリで使用することができません。
f:id:tuti107:20160420145003p:plain
前回開発したアプリで360度立体視表示するためには、以下のような形式への変換が必要となります。
f:id:tuti107:20160420141059p:plain
以前はこの変換を自力でやる必要がありました(例えばこちらなどで取り上げられています)。しかし先月リリースされたRICOH THETA UVC Blenderを利用することで、Dual Fisheye形式ではなく変換後の形式でのライブストリーミングが可能となりました。
RICOH THETA UVC Blenderは、こちらよりダウンロード可能です(ライブストリーミング用アプリ、という名前です。なお基本アプリを未インストールの場合は、こちらを先にインストールしておく必要があります)。
インストール後、Theta Sの電源を入れずに、PCとTheta SをUSB接続し、THETA UVC Registerを起動してください。
f:id:tuti107:20160420142632p:plain
これで、そのTheta SがTHETA UVC BLENDERとして登録されます。試しに、Googleハングアウト等、USBカメラ画像を取り込むことができるアプリにて、カメラリストを表示してみると、THETA UVC BLENDER(***)が追加されていることを確認できます。これを選択すると、Dual Fisheye形式ではなく、本開発アプリで利用可能な形式にて表示されます。
今回は、右目・左目用の二台のTheta Sがありますので、それぞれ上記の手順で登録を行いました。

Open Broadcast Software

次に、撮影画像をブロードキャスト配信するための用意を行います。いろいろな方法・ソフトウェアがあるようですが、調べたところ、Open Broadcast Softwareを利用するのが良さそうです。Open Broadcast Softwareは、こちらからダウンロード可能です。
このアプリは、カメラキャプチャ映像のみならず、静止画・ウィンドウ・画面全体など様々なソースを組み合わせて一つの動画を構成し、これを録画・配信する機能を備えています。例えば、以下のように右目・左目用それぞれのTHETA UVC BLENDERを縦に並べて配置すると、あっという間に360度立体視動画の形式になります。
f:id:tuti107:20160420144221p:plain
ところが、実際この方法ではうまくいきません。右目用と左目用の映像が全くシンクロせず・フレームレートもバラバラのため、本映像を前回のアプリで視聴しても全く立体視動画には見えません。そこで、右目・左目をシンクロさせて縦に並べる方法を検討してみます。

OpenCVで二つのTHETA UVC BLENDERをキャプチャ・合成

できるだけ簡単な方法で、といろいろネットを探索したのですが、残念ながらコードを書くのが一番手っ取り早そうです。今回は、OpenCV3.1 + Javaで、二つのTHETA UVC BLENDERをキャプチャ・合成のコードを作成しました。
なお、OpenCV3.1の導入とJava(Eclipse)での利用手順については、設定が少し面倒なのですが、こちらにわかりやすく手順がまとめられておりますので、これを参考に進めてください。なお今回、別にJavaである必要性は特にないのですが、現在Macで開発している本環境を近日中にWindowsへ移植することを検討しており、移植性を考えてJavaにしてみました。
コードは以下の通りとなります。なお、24行目・25行目のnew VideoCapture()の引数値は、実行環境毎に異なります。それぞれ左目・右目用のTHETA UVC BLENDERの映像が取れるように調整をしてください。

これを実行すると、以下のように、二つのTHETA UVC BLENDER映像が縦に並べられた映像が表示されます。
f:id:tuti107:20160420151352p:plain
このプログラムを起動した状態で、再度Open Broadcast Softwareを起動し、今後は、ソースとしてウィンドウキャプチャを選択してください。
f:id:tuti107:20160420152052p:plain
空の名前でウィンドウを表示をチェックすると、ウィンドウから、先ほど起動したプログラムのウィンドウを選択可能となります。表示サイズがおかしい場合は、設定→映像→キャンバス解像度を1280x1440に設定の後、赤枠の丸部分をドラッグして、位置・サイズをキャンバスの大きさに合わせてください。
f:id:tuti107:20160420152846p:plain
f:id:tuti107:20160420152859p:plain
これで左右両眼の映像のタイミング・フレームレートがあった形での映像配信が可能となります(ただ当方のMacではすでに処理の限界に近づいており、ファンが猛烈に周り始めました)。

配信用のサーバを用意する

わざわざサーバを立てなくても、UStream等の既存のライブ配信サーバーを活用すれば、上記の設定だけで動画配信が可能です。ただし、インターネット上のサーバへアップロードするためレスポンスはそれ相当となってしまいます。今回はメイカーフェアー向けに可能な限り高速な動画配信を行いたいため、ローカルでサーバを立ち上げ、ローカルネットワーク内でのみ動画配信を行う形としました。
HLS形式のライブストリーミングを配信可能で、かつ軽量なサーバとしては、nginxというWEBサーバの人気が高いようです。なお、nginxはデフォルトでは、ライブ配信用のモジュール「nginx-rtmp-module」がdisableのため、これを有効化してコンパイル・インストールする必要があります。
nginx導入の手順、およびライブ配信のためのOpen Broadcast Softwareの設定については、こちらを参考にさせていただきました。なお、当方の環境(Mac)に合わせて、./configureで設定するパスを/usr/local/...に変更しました(/usr/local/etc/nginx/nginx.confのrtmp設定についても同様)。Open Broadcast Softwareの配信設定については、こちらに記載の通り、以下のように指定することで、http://PCのIPアドレス:8080/test.m3u8へアクセスすることで、前回開発したアプリからTheta Sで撮影の360度立体視映像を視聴することができました(冒頭、及び以下のCardboard映像は、本仕組みで視聴した我が家の天井です)。
f:id:tuti107:20160420160111p:plain
f:id:tuti107:20160420162743j:plain

まとめ

今回は、前回開発したCardboard用360度立体視動画ビューワーにて、Theta S(左右両眼用)で撮影・リアルタイム配信した映像を視聴するための環境を実現しました。確かにCardboardでTheta Sで撮影の映像を視聴することはできるのですが、処理負荷の高さからフレームレートは数FPSという状況、またライブ配信の遅延が20秒近くあるため、メイカーフェアーで「リアルタイム配信」を謳うのは厳しい感じの仕上がりです。
次回は、一旦Cardboardから離れて、Oculusにて、PCで取り込んだ右目・左目映像を直接表示する仕組みを作ってみたいと思います。