2016年10月13日木曜日

dlibで顔認識して、leap motionで手の動きとって、unityの人体モデルを動かしたよ!

ひみつのクエリちゃん


前回までのあらすじ


美少女の中の人になる、全人類の夢ですよね?<一部男子の間違いw

以前 @goroman さんが紹介していたのfacerig、凄かったです。
https://twitter.com/GOROman/status/686408594674159616

全身モーションキャプチャなんて、凄いですよね、Perception Neuron一度試してみたい!
https://kila.amebaownd.com/

その後に utibenkei さんがunityでFaceRig使って、先こされました!
http://qiita.com/utibenkei/items/15925db826721f6bb00c

先日のcedecでは @warapuri さんが作っていたKinect使ったpepper君の制御、感動しました!
https://twitter.com/warapuri/status/768611348062277632

で、自分もクエリちゃんで色々動かせるようになってきたので、ブログにまとめる事にしました。
(このタイミングで、マスコットアプリ文化祭にも提出予定です。)

動画はその内ちゃんとしますが、以前撮ったtwitterのやつ付けておきます。
(今見ると動きがキモイです…面目ない)

12/31 本日アップデートしました、ノーマルバージョン、ハロウィンバージョンに続き、クリスマスバージョンも追加しました。

技術情報

  1. 手の動きの取得 leap motion
    • leap motion orion ってすっごい認識精度ですよね。
      あれ使って手の動きと、手のモデル表示しています。
      今回は、VRではないので頭の前にleap motionをマウントできません。
      なので、胸に付けて使っています、ネックマウントleap motion!
    • https://www.leapmotion.com/?lang=jp
  2. 人体モデルの制御 SAFullBodyIK
    • leap motionから拾った座標を、手首から上の腕のモデルの制御で使っています。
      あ、unity asset の FinalIK でもいいかもです、いつか買って試したい。
    • http://stereoarts.jp/
  3. 顔の位置の取得 dlib
    • ノートパソコンなどのwebカメラで自分の表情が映るようした時に、
      上記SAFullBodyIKに、首の座標をunityのassetのdlibで解析した値で制御しています。
      微妙に反応悪いのは、フルタイムで反映すると誤差でブルブル震えてたからです…。
    • https://www.assetstore.unity3d.com/jp/#!/content/64314

  4. 顔の表情の取得 OpenCV dlib
  5. 顔の表情の変更 Query-chan
    • こちらはクエリちゃん使った事ある方ならもう説明不要ですよねw
      残念ながら顔の表情のモーフとか無いので、目パチと口パクだけテクスチャ制御で対応しています。
    • https://www.assetstore.unity3d.com/jp/#!/content/20031
  6. ボイス追加
    • 本当ならマイク+ボイスチェンジャーで中の人になるべきだったのですが、
      クエリちゃん付属のボイスを鳴るようにしておきました、声に合わせて演技するカンジで
    • http://query-chan.com/
  7. ローパスフィルタ追加(12/31)
    • 本日差し替えた実行ファイルでは、顔の座標にローパスフィルタを追加しました。
      移動時のブルブルが減っています。<カメラから拾った輪郭が安定しない為?
    • 以下、goroman氏のtwitterより

ダウンロード


とりあえずgoogle driveに置きました。
「ひみつのクエリちゃん」
「ひみつのクエリちゃん」<12/31更新しました。
(unityから出力した、windowsのx86_64x86のexeファイルです)

試す際は、一応実行前にウィルスチェックお願いします。
leap motionの実行時に最新のドライバが必要です。

某くまのぬいぐるみに話しかけるやつをまねて名前付けてみたのですが、わかりずらかったかも?
遠隔地から映像だけ送れば、子供とか騙せないかな~<まだ不自然すぎて無理だろw

webカメラがあれば、頭の位置と表情だけは反応すると思います。

ネックマウントleapmotionですが、unity上で以下のようにおいてあります。

この写真の様に、首から下の胸あたりから正面向いて配置されると正しく認識します。

その際、leap motionを胸に置かないといけないので、ヤケドしないように気を付けてください。
(テーブルの上に設置するやり方、leapmotion orionでもできるならいつか試してみたい。)



使用した unity asset







謝辞


クエリちゃんのモデル、いつもデータ使用させていただいています、ありがとうございます。
"Query-Chan model" by Pocket Queries, Inc. is licensed under a Creative Commons Attribution 4.0 International License(CC-BY).


2015年12月30日水曜日

2015年 全天球パノラマ動画メモ

Unityで360度パノラマ動画を作成してみた



Spherical Image Cam(昔やってた方法)

Unity4の頃は @warapuri さんの記事を参考に無料版を使って360度パノラマ動画作ってました。
spherical-image-camを使ってunityで全天パノラマ動画を作ろう(No hack, no work)
VR Creative Award 2015にチャレンジできたのはSphericalImageCam(無料版)のおかげでした、ありがとうございます。
ですが、Unity5になってから、もう少し大きな画像サイズで作成したくなりました。


360 Panorama Capture(今やってる方法)

そこで、Unity5.1.2以降で使える以下のassetに乗り換えました。
360 Panorama Capture(UnityAssetStore)
こちら、設定によってはVRCHIVEへ自動アップロード機能があるのと、readmeが英語なので注意が必要ですが、便利だと思うので手順を紹介します。(ほぼreadme通りです)
  1. Unity5.1.2以上を使って再生できるシーンを作成する。
  2. 空のゲームオブジェクトを作成し、キャプチャパノラマスクリプト(CapturePanorama.cs)を追加します。
  3. CapturePanoramaの設定をします。
    • 「PanoramaName」に適当なファイル名の先頭文字列を指定します。
    • 「CaptureStereoscopic」は360度パノラマステレオ動画作成時にチェックします。
    • 「PanoramaWidth」は横幅を指定します、4096くらいあれば十分ではないでしょうか?(8192で後から縮小でも可)
    • 「SaveImagePath」に連番画像の書き出し先ディレクトリを指定します。
    • 「CaptureEveryFrame」をチェックします、静止画でなくFrameRateに対応した連番画像が書き出されます。
  4. Unityのシーンを実行します。
  5. 任意のキー入力でキャプチャを開始します。(デフォルトは「p」)
  6. 以上で??????_2015-12-31_23-59-59-999_00000.pngみたいな画像が準備できたはずなので、あとは煮るなり焼くなりお好きにどうぞ。

ハコスコストアへアップロード

クエリちゃんと夕方の秋葉原でジェットコースター(ハコスコストア)
ハコスコのプレイヤーが優秀な為、PCのブラウザ上で見たり、タオバイザーで見る場合はここお勧めです。上記の動画はffmpegで連番画像から動画へコンバートしています。
ffmpeg -r 30 -i Red_%05d.png -s 4096x2048 -aspect 2:1 -pix_fmt yuv420p -c:v libx264 panorama.mp4
この時は4096x2048で作成してしまいましたが、解像度は3000x1500が正解のようです。

youtubeへ360度ステレオ動画としてアップロード

【VR Video】クエリちゃんと夕方の秋葉原でジェットコースター(youtube)
唯一360度ステレオパノラマ動画に対応していますが、なぜか16:9です。上記の動画はffmpegで連番画像から動画へコンバートしています。
ffmpeg -r 30 -i Red_%05d.png -s 3840x4320 -aspect 8:9 -pix_fmt yuv420p -c:v libx264 panorama_y.mp4
動画作成後に、専用アプリでVR Videoである事を証明するメタデータを追加してください、詳細は以下のyoutubeヘルプ参照。
360 度動画のアップロード(youtubeヘルプ)
UnityでなくMMDなら以下のサイトを参考にすると、youtubeへの道が開けそうです。
【VR Video】YouTubeが360度パノラマ+3Dステレオ動画アップロードに対応したので試してみた【Cardboard】(@youten_redoさんのブログ)

niconicoVR用にアップロード

【360度パノラマ】クエリちゃんと札幌でVR乗馬ダイエット(ニコニコ動画)
GearVRで注目が集まってるらしいです、上記の動画はffmpegで連番画像から動画へコンバートしています。
ffmpeg -r 30 -i horse_%05d.png -s 2560x1440 -aspect 16:9 -pix_fmt yuv420p -c:v libx264 panorama_n.mp4
動画解像度はGearVRで1440pあたりが限界とみていますが、2048x1024なら多分大丈夫だと思います。(4Kだとヤバいとか?)
あとniconicoVR用に「Equirectangular」のタグを忘れずにつけましょう。

補足

こちらに記載した情報は2015年末の時点の物で、できるだけ正しい情報になるよう調べましたが、無保証です。
360 Panorama CaptureにカメラのImageEffectがどこまで使えるか未検証です、重要な所なのに申し訳ありません。

使用した unity asset





謝辞

ゼンリン様のマップとクエリちゃんのモデル、いつもデータ使用させていただいています、ありがとうございます。
Japanese Dosanko City by ZENRIN is licensed under a Creative Commons Attribution 4.0 International License(CC-BY).

"Query-Chan model" by Pocket Queries, Inc. is licensed under a Creative Commons Attribution 4.0 International License(CC-BY).


2015年7月25日土曜日

「Japanese Dosanko City」で札幌で乗馬デートしてみた。

札幌でクエリちゃんと乗馬デートしてみた!

みんな大好き秋葉原以降、大阪、九州と無料公開されたZENRINのunityアセットの最後の札幌の話です
Unity向け3D都市モデルデータ「ZENRIN City Asset Series」|ゼンリン
先日、ゼンリンさんが無償提供している札幌のマップを使って、まっすぐ馬で駆け抜けるAndroid用アプリを公開しました。
JdcJockey360VR
正直、特に面白くは無いのですが、Cardboard で乗馬したかったので目的は達成しました!(VRHMD楽しい)
せっかく作ったので、札幌のマップのassetについて、覚えている範囲でレポートします。


境目が見えない工夫

今回一番感動したのが、半球のドームと、町並みの遠景です。 上手く使えばかなり街の果て感が軽減され、良さそうに思えました。

(実は今回はfarが近すぎるので全く写らず、どちらも非採用なんですけど)


街は碁盤目のよう、凄い再現性

google map 札幌時計台と比較してもスゲー似てます!


今回もA~Iまでの9つのエリアに分割

で、札幌の土地が微妙に曲がっているので、道やエリアも微妙にはみ出たりしています。
本当は大通り公園をクエリちゃんと乗馬予定だったのですが、外でちゃいそうなので諦めました。
(代わりに時計台の近くのD~Fを採用だよ、中心地の(マップ的に)美味しい所だよ!)



例によってスケールはw

街めっちゃ小さいです、普通の人のサイズ置いたら巨大メカですw
10倍くらいだったと思いますが、適時スケール調整が必要です。


おまけゲーム付き

今回のおまけはSDクエリちゃんとそのゲームでした、SDクエリちゃん軽いのでゲーム用途ではいいかも?
(すいません、自分SDの方を馬に絡める手段が思いつかず今回は未使用です)

なんか思ったより書く事少なかった上にtwitterコピペでZENRINのassetの良さ伝わってない感ありますが、
unityちゃんシール是非お願いします。

使用した unity asset





謝辞


Japanese Dosanko City by ZENRIN is licensed under a Creative Commons Attribution 4.0 International License(CC-BY).

"Query-Chan model" by Pocket Queries, Inc. is licensed under a Creative Commons Attribution 4.0 International License(CC-BY).

2015年1月10日土曜日

「Japanese Otaku City」で秋葉原をCardboardでドライブしてみた。

秋葉原を疾走するアプリ作ってみた!

去年ゼンリンさんが無償提供している秋葉原のマップを使って、街中をクルマでドライブするAndroid用アプリを公開しました。
JocDrive360VR(GooglePlay)

密かに Cardboard や タオバイザー や ハコスコ に対応しています(VRHMD楽しい)

最初は以下のサイト真似すれば楽勝とか思ってたのですが、正直、結構マップ使うのしんどかったので、覚えている範囲でメモします。
MacとUnity Free版を使ってZenrinさんの秋葉原上空をQueryちゃんがOculus DK2で飛ぶ、方法
↑ここだけ見ればある程度遊べるようになるんじゃないかと、神サイト!

Unity Free 版だとあちこちピンク

いきなり酷い仕打ちですwサンプルシーンをロードしたらモデル化けまくってました。
ちょっと検索するとヒント出てきたので、単純なのはDiffuseで、樹木のようなα付きテクスチャは半透明用だったかな?
とにかくシェーダー変えまくりました。

ちょっと町小さくね?

unityってだいたい1グリッドを現実世界の1メートルで考えてる人多いと思うんですよ。
どう考えても小さすぎるのでスケール5倍してます、もし汎用キャラじゃなければ他を縮小してもいいかも。
(良く見るとサンプルのクエリちゃん超縮小されてるしwww)

いらない部品大杉、修正しる!

使いたいのは秋葉原のマップです。
PQ_Remark_AKIHABARA のモデルだけ使う事にして、それ以外は捨てました。
(Androidのアプリでは処理負荷の関係もあって断念しました。)

あれ、tpsの人間置いたら落ちちゃうんだけど。

確か床の当たり判定無かったような(すいませんここうろ覚え)
作りたいのがレースゲームだったので、PQ_Remark_AKIHABARAの中の二つだけ判定入れました。(readmeみたらgroundって書いてあったので)
PQ_Ground
PQ_Road
(川とかは下の処理で進入禁止にしてますwww)

マップ広すぎ、何処走ればいい?

ビルの判定の代わりに進入禁止エリアを作って、看板と見えない背の高いBoxで蓋しています。
レースゲームなんでクルマは道にへばりついているのでこの方法でOKなはず。
もしアーマー○・コアの様な空飛ぶメカならビルの判定まじめにしないとですね。

全然処理重いんだけど!

Androidアプリが目標だったので、これ重すぎてかなりやばいです。
1.とりあえずDive_cameraのZfarかなり近くしました、50~100を行ったり来たり。
2.Zfarより遠いビルはブロック毎表示Off、Block_A~Iに分かれてるんで簡単w
3.マップ西側にいる時は東の高速道路を表示Off、みたいなのをちまちまやったけど全然効果でず。
4.このあたりでブチ切れ!ビル間引く事にしました、Block_?の中の見えなさそうなビルをかたっぱしから永久表示Offにしました。
ゲーム向けならもっとビル手抜きしてそれっぽく軽く作ってくれると思うのですが、ゼンリンさんマジメ過ぎる・・・

で、結果以下のようにスッカスカになりました。本物のゼンリンさんのアセットより見栄え悪くてごめんなさい。

左が通常マップで、右がビルを間引いた後のマップです。(遥か上空からの写真です、南が上なのはBlock_Aが南だからwww)

ところでプロは凄い!

秋葉原の町使った奴他にも見たのですが、巨大クエリちゃんと闘う奴凄いですね。
【東京ゲームショウ】Otaku Cityアキバに現れた巨大クエリちゃんを撃墜せよ!
この重い秋葉原マップ使ってアクションゲーム作っちゃうなんて!(ポケット・クエリーズ、スゲー!)

さらにAndroidアプリでも超軽い奴が!
tAkibaWalk side-by-side app(GooglePlay)
飛んでるだけで判定無しだと考えても、どうやってるか見当もつかないっす、これを数時間で作ったとか?!(タオソフト、恐るべし)

Global Game Jam ?


なんで今更去年のアプリの話?ですが、今月開催されるGlobal Game Jamでゼンリンの地図が無償提供されると聞いたので、参考になればと書きました。
まぁGameJamでここまでシビアに高速化する必要ないとは思いますが、是非何かの参考に<高性能PC羨ましすぎる!
ゼンリンの「3D都市モデルデータ」、世界的ゲームハッカソン「Global Game Jam」で無償提供 (InternetWatch)

ところでゼンリンさん、もう一か所くらい無償公開されたら、秋葉原で使ってた暇人が移植っぽく利用してくれると思うですが、どうですか?(笑)

2014年12月14日日曜日

Google CardboardSDK を使ってみた

CardboardSDK 発表!


先日、google が スマフォVR Cardboard 用に新たにSDKを発表しました。
https://www.google.com/get/cardboard/

今まではUnity+DiveSDKを使っていたのですが、
たまにすーっと左右に加速したままになるドリフトに悩まされていたので、
この機会に試してみる事にしました。

この記事は スマフォスロットイン系HMD Advent Calendar 2014 の14日目の記事です。

初日


まずは以下のサイトからダウンロードしてきました。
https://developers.google.com/cardboard/unity/download

サンプルを起動した所、なんか真っ暗で写りません・・・。
おかしいなぁと思って調べたら、以下の記述を発見しました。

> Requires Unity version 4.5+ and licenses for Unity Pro

え~?!Unity Pro が必要でした!
仕方が無いので、二画面の時の処理を呼ばないようにしたらなんとか表示されました。


えっと、これじゃ 駄目ですよね・・・初日はここでギブアップしました。

二日目


とりあえずサンプルを動作させる為に、unity pro版のtrial起動させてみました。
(ユニティちゃんディレクターズカップで使用する為のライセンスで、動画投稿もしたのですが、それは又別の機会に。)
その結果がこれ。


おぉ、なんかいいじゃないですか~、でもunity freeで作らないと公開できないし、
せっかくだからDiveで同じシーン見てみました。


こ、これは酷いですね。自分ちゃんと知らなかったのですが、
最近のVRHMDは広角レンズで強引に視野を広げる為、カメラで言う所の糸巻型に湾曲するんですね。
それを逆にソフトウェア側(shader?)で樽型に補正が必要だったとは・・・。
きっと Oculus Rift DK2 とか持ってる方はとっくに気が付いていたのだと思うのですが、
没入感の不足は画角の不足と勘違いしていたので、それに気が付けただけでも良しとします。

というわけで、CardboardSDKについては、結局 Unity Pro 買わないと使えない、
という事がわかっただけでした、それでは。

2014年11月14日金曜日

unity+diveでカメラの画角を変更する。

首の制御で失敗した~!


 最近クエリちゃん360VR(google play)をちょっと改良したのですが、
その際にカメラの方向を見るようにしました。
例によって以下のサイトからプログラム持ってきただけですがw
 http://www40.atwiki.jp/spellbound/pages/1408.html

で、最初強めに方向制御したら、人間とは思えない状態になってしまいました、グキッ。

こりゃあかん、って事で今は角度抑えめで微妙に入ってる状態です。
(制御良くわからんです、すみませぬ)

本題、diveのfov効いてなくね? 


前回、ハコスコに対応する為にDiveSDKのプログラム変更してましたが、
もともと参考にしたサイトが書いていた、fieldOfView(以下fov) を45に変更ってのは、
無効の様に見えました(実際右カメラに設定しても駄目だった。)

それで、DiveSDKのカメラのOpenDiveSenser.csを見た所、
独自のprojection変換行列が使われているようでした。(詳しくは以下)

http://docs.unity3d.com/ScriptReference/Camera-projectionMatrix.html

標準のパースペクティブカメラと違ってfovの値関係なさそうなので、
行列に入力される値を弄って画角かえます、具体的には以下の部分ですね。

cameraright.projectionMatrix = PerspectiveOffCenter((-zoom-correction)*(znear/0.1f), (zoom-correction)*(znear/0.1f), -zoom*(znear/0.1f)*aspectRatio, zoom*(znear/0.1f)*aspectRatio, znear, zfar);

後ろ二つのnearとfarは関係なさそうなので、テストで0.1fって値を4か所、右カメラだけ0.05fと小さくしてみました。
cameraright.projectionMatrix = PerspectiveOffCenter((-zoom-correction)*(znear/0.05f), (zoom-correction)*(znear/0.05f), -zoom*(znear/0.05f)*aspectRatio, zoom*(znear/0.05f)*aspectRatio, znear, zfar);


なんか右だけ広角っぽくなってますね!

なので、該当部分を以下みたいに書き換えてparamを0.1より増やせば望遠、減らせば広角になるのではないでしょうか?

float param=0.1f;
cameraleft.projectionMatrix = PerspectiveOffCenter(
(-zoom+correction)*(znear/param), (zoom+correction)*(znear/param),
-zoom*(znear/param)*aspectRatio, zoom*(znear/param)*aspectRatio,
znear, zfar);
cameraright.projectionMatrix = PerspectiveOffCenter(
(-zoom-correction)*(znear/param), (zoom-correction)*(znear/param),
-zoom*(znear/param)*aspectRatio, zoom*(znear/param)*aspectRatio,
znear, zfar);

fovと違って値から絵が予想できないのですが、何度かテストすれば最適な画角が得られそうです。
cardboardとハコスコ両方でdiveつかったり、タオバイザーのレンズを広角に変更したりする場合は試してみてください!

"Query-Chan model" by Pocket Queries, Inc. is licensed under a Creative Commons Attribution 4.0 International License(CC-BY).

2014年11月7日金曜日

cardboardやタオバイザー用にunity+diveで作った物をハコスコ対応にする。

はじめに

先日、クエリちゃん360VR(google play)というのを、cardboard用にunity+diveで作成しました。

ほとんど以下のスライドを見ながらサンプルを少しいじっただけです。
http://www.slideshare.net/NobuhikoSasaki/ss-38173018

あ、カメラを回す部分は以下のサイトを参考にしました。
http://greety.sakura.ne.jp/redo/2014/09/durovis-dive-sdkcardboard.html

更に、以下のサイトの最後を参考に、ハコスコにも対応しました。
http://warapuri.tumblr.com/post/98800390873/spherical-image-cam-unity

ハコスコ対応

ハコスコ対応だけハマったので詳しく書きます。
入力を制御してる適当なクラスの上の方に変数を追加します。


  public bool doubleCameraFlag = true;


更にupdate関数で以下の様に書いていました。
先ほどのサイトに書いてる事だけだと絵が潰れるので、aspect比も変更しています。
(本当は座標も補正した方が良さそうです、ハコスコの時ちょっと近いwww)


  // タッチ情報を取得する
  TouchPhase touchPhase = TouchPhase.Ended;
  if (Input.touchCount > 0)
  {
   touchPhase = Input.GetTouch (0).phase;
  }
  // タッチ直後?
  if ((touchPhase == TouchPhase.Began) ||
      // マウスが押された瞬間?
      (Input.GetMouseButtonDown(0)))
  {
   doubleCameraFlag ^= true;
   GameObject diveCamera = GameObject.Find("Dive_Camera");
   if (doubleCameraFlag == true)
   {
    // 左カメラ復活
    diveCamera.GetComponent<OpenDiveSensor>().cameraleft.enabled = true;
    // 右カメラを元に戻す
    //diveCamera.GetComponent<OpenDiveSensor>().cameraright.fieldOfView = 85.0F;
    diveCamera.GetComponent<OpenDiveSensor>().cameraright.rect =
     new Rect(0.5F, 0.0F, 0.5F, 1.0F);
   }
   else
   {
    // 左カメラ停止
    diveCamera.GetComponent<OpenDiveSensor>().cameraleft.enabled = false;
    // 右カメラ補正
    //diveCamera.GetComponent<OpenDiveSensor>().cameraright.fieldOfView = 45.0F;
    diveCamera.GetComponent<OpenDiveSensor>().cameraright.rect =
     new Rect(0.0F, 0.0F, 1.0F, 1.0F);
   }
   // アスペクト比も変更
   if (doubleCameraFlag == true)
   {
    diveCamera.GetComponent<OpenDiveSensor>().aspectRatio=
        (Screen.height*2.0f)/Screen.width;
   }
   else
   {
    diveCamera.GetComponent<OpenDiveSensor>().aspectRatio=
        (Screen.height*1.0f)/Screen.width;
   }
  }

で、このプログラム外部からDive_Cameraを制御しているのですが、
何故かDive_Cameraのupdate関数ではUnityEngine.TouchPhaseが使えませんでした。
またいつかエラーになる原因を調べたいです・・・。