ハトマスクをおみまいするぞアプリ
tiktokに指定したエリアに入ると目がぱっちり、小顔になる加工フィルタがあるらしい。で、これをハトにするのがあったら面白いのではという話。 森さんからFacebookで面白いですよねって話が。確かにあると、面白そう!
静止画で( ゚Д゚)の位置を検出して、それに合わせたハトマスクを作ることができるかどうかから始めればいいかな。
Unityでできるらしい
UnityとXamarinってなんか関係あるのかな?
2019.08.09
アセットを買ってみた。15Kは高い。うまく動かないのでヤバい。
2019.08.10
以下の2つを忘れていたらしい。
Assets配下にStreamingAssetsをフォルダごとコピーする
ToolsメニューにあるOpenCV, Dlib のSet Plugin Import Settingsをする
明日は、コード読みだなぁ。
FaceMask Sampleのコードを読んでみることにした。
が、むず過ぎるので、DlibとOpenCVの説明を読むところからにする。
FaceMask Sample
FaceMask Dataには写真 + LandmarkPointsが68個設定されている。
Dlib
TextureExample2D.cs
88: FaceLandmarkDetectorにTexture2DをSetImageする
91: FaceLandmarkDetector::Detectで結果を取り出す (List<Rect>)
98: RectをFaceLandmarkDetector::DetectLandmarkに渡して、位置情報をList<Vector2>で取得する
実際には使ってないようだ
106: FaceLandmarkDetector::DrawDetectLandmarkResultで、結果を書き出すことができる
111: FaceLandmarkDetector::DrawDetectResultで、認識した顔のRectを書き出すことができる
ここまでを使って、指定した写真を解析、結果を描画するアプリを作れるかどうかがまず最初かも?
Texture2Dはテクスチャをいじるためのクラスらしい。
Vector3というクラスも出てきた。Unityだとおなじみのものらしい。
なんとなくわかった感じで一旦終了。
Unityのチュートリアル
本格的にいじる前に、Unity自体のチュートリアルをする。
Updateではなく、定期的に呼び出されるFixedUpdateというメソッドを使っていた。(Updateは毎フレームごとに呼び出されるのだとか)
完了。上記以外はだいたい理解できる内容だった。英語は1/3くらいだけども。
というわけで、明日は実際にDlib使ったアプリを作ってみよう。(サンプルと同じコードをコピペして、素のプロジェクトから作る)
カメラ画像をDlibを使って顔認識させるアプリを作る
カメラ画像を表示するプログラムをまず作ってみる。WebCamTextureというものを使うとできるらしい。便利。
上記でグレースケール化するところを、Dlibを使って顔のパーツを認識させ、描画させればOKのような気がする。
なんとかできた。重いけど。
鼻の位置に合わせてCubeを表示する
これで、目、鼻、口の場所がだいたいわかるはずだから、それに合わせてハトマスクを表示すればOK?
まずは雑に鼻のところを中心として、ハトマスクの画像を表示するところからやってみよう。
以下のページで紹介されているように、68個のランドマークを使って?解析した場合、鼻のてっぺんは31番目に当たる。
31番目の位置を、Unityの座標(Scale)に変換して、Cubeを配置するところまでができた。
次は顔の大きさを取得して、Cubeの大きさを変えてみよう。
顔の大きさに合わせてCubeの大きさを変える
顔の大きさは Rect.height, Rect.width でだいたいわかるので、それに合わせてScaleを変更すればOK。ということでできた。
ただし、額より上のところはカバーできてない。FaceLandmarkで取れるRectは眉毛からあごまでだから仕方がない。
単純に1.25倍するくらいでいいのかな?? (これは後にしよう)
顔の向きに合わせてCubeの向きを変える
以下のページを参考に。変数名などはQiitaの記事を参考にした。
推論するのは平行移動と、回転移動。で、今欲しいのは回転移動。(ということにする)
顔向きの推定にはベクトルや行列が出てくるので、以下の記事を読んでみた。が、まだ理解ができない...orz
この記事に回転ベクトルから、クォータニオンへ変換する方法が書いてあった。なんとなく追従している感じ。
code:cshap
var rod = new Vector3(RotationX, -RotationY, RotationZ);
this.transform.localRotation = Quaternion.AngleAxis(rod.magnitude * 180 / Mathf.PI, rod);
顔の位置が変わると、なんかおかしい。Y軸の回転が逆になってる。
おそらく、顔向き推定に利用するパラメータの値が間違っているのだろう...。でも、ここを理解するのはちょっと大変そうだ。
なんとかなったんだけど、なぜか説明ができない...orz
座標系じゃないかと思うんだけどなぁ...。
Cubeをハトマスクっぽくしてみる
顔に四角が表示されるだけなので、これをハトマスクっぽくしたい。
3Dモデルを作るのが一番なのだろうか??
Unity Assets Store にフリーで狐のお面があったので、それを使ってみる。
https://gyazo.com/22bb512713797e09007ac262c8257fb9
お面の拡大倍率を変えてあげれば、既存のコードで問題なく動いた。んだけど、なぜか天地が逆になる。
天地逆 = X軸の回転がなんだかおかしいらしい。うーむ。どうすればいいのだろうか?
(小手先でパラメータいじるだけではうまくいかなかった...)
ちょっと視点を変えて、顔が増えたときに、動的にお面が増えるようにした。こっちはそんなに難しくない。
作ったオブジェクトはいちいち消すべきなのかどうか悩む。今の所 disactive して見えなくしてるけども。
とりあえずiPhoneアプリにしてみる
Macのアプリにしたら、問題なく動いた! (お面は天地逆のままだけども)
iPhoneの方はカメラを内側にしてなかった & そもそも重すぎてダメ。
iPhoneでカメラの画像が出てこないので、WebCamTextureのみを使ったサンプルを作って実験。
問題なく動いているので、コードが悪い。
カメラ画像が表示されなかったのは texture をいじった後、Apply を呼び出してなかったから。
Unityのデバッグモードや、MacのアプリだとApplyなくても表示されたのだけど、iPhoneだとダメらしい。
ビルドが長いのが考えもの。インポート最低限にしたいけど、どれを除けばいいのかよくわからないのよね...orz
なんとかアプリとして動作してることがわかった。複数の顔にも対応することは対応する。
以下の写真にマスクをかぶせてみたもの
https://gyazo.com/7ac74a3d2fcd00474094946468d0855b
ここから精度を上げるか、ハトマスクに行くか。雑でもいいからハトマスクに行こう。
ハトマスクの3Dモデルを作る
作っている人はいなさそうなので、自分で作るしかなさそう。Blenderを使ってまずは雑なハトマスクを作ろう。
https://gyazo.com/c2cb196fcfba03452ab3697e29e0c403
まずはこんなのから。Unityで取り込めて、マスクとして使えるんだけど、そうなると、マスクの天地逆がぁぁぁぁ。
強引にZ軸中心に180度回転させてみたら、なんとかここまできた。(Z軸の回転に何かしら問題があるらしいのだが...)
https://gyazo.com/110f5b071987ab5fcbde2221d5a3f223
マスクっぽくする
写真を見るとマスクっぽくない。お面の時はお面ぽかったけども。
以下の理由でマスクっぽくないのではないかと予想。
顔を覆えてない
顔の位置より手前にあるように見える
大きさと、位置について修正を試みる。
大きさ
まゆから顎までの長さに準じて大きさを変えているので、適当な倍率で大きくすればいいんだと思う。
1.3倍くらいでいい感じになったので、その辺にしておく。
位置
今は鼻の頂点の位置と、マスクの中心が合うようにしている。
頭の中心 = X軸とZ軸における中心とマスクの中心が合うようにすれば良いはず。
頭の中心は、鼻の頂点から、ある一定の距離Z軸方向に移動したところにある点と考えれば、算出することができる気がする。
横顔の写真などを見ると、鼻の頂点から頭の中心?までの距離は、目尻からあごまでの距離と同じくらいらしい。
目尻からあごまでの距離は解析結果からわかる。(顔の角度は置いとくとすると)
どうも位置は難しいので、後回しにする。
今の進捗はこんな感じ。
https://gyazo.com/2435850c9a80be13dc092340b4d9ce92
比較して分かったことだけど(今更)、ハトマスクってかなり布っぽいんだなぁと。
この布っぽさをモデル側で演出できれば。
ハトマスクのモデルの精度を上げる
を見ながらモデリング。7時間くらいかかった。
格段のでき!!! 紙袋見たいといわれてしまったけども...。
https://gyazo.com/dd4b373bf961ba3bbed3b6692fabbbba
さっきの画像に適用するとこうなる。まぁいい感じ。
https://gyazo.com/58e565e64112d6968873448e950f5445
iPhoneで動かすとボタンやテキストがものすごく小さくなる
これは困るのでなんとかしたい。
Canvas、Panelの制御で一苦労。
iPhoneのカメラのように上下、左右にUIをだす領域を確保して、中央に4:3でカメラ画像をだすことにする。
これをやるのに丸1日かかった...orz
ただ、詰まったのは以下のところだったと思われる。
解像度に合わせてUIをスケールさせる方法
Canvas ScalerでScale with Screen Sizeを選択する
この時点でデフォルトを iPhoneSEの画面サイズ(640x1136)にした
UIパネルのサイズ変更
RectTransformのsizeDeltaを使う
親キャンバスにアンカーする方法
RectTransformのanchor
カメラについて調べる
1つ前で、解像度やiPhoneの向きに合わせてUIをスケールさせるところができたものの、カメラ画像を表示すると以下のようなことが起きた。
Portraitの場合: 天地が逆に表示されている。横方向に延びている感じ。
Landscapeの場合: 左右が逆に表示されている。縦方向に延びている感じ。
いくらか調べて、わかったこと。
WebcamTextureをデフォルトで呼び出した際の解像度
iPhoneX: 640x480
MacBook Air: 320x240
顔検出や顔向き判定するのに使うので解像度はこちらで指定したほうがいいかも
WebcamTextureを設定するGameObjectのアスペクト比を1.33にするとちょうど良い
WebCamTexture.videoRotationAngle というプロパティでiPhoneの向きがわかる
4つ目と組み合わせると、簡単にiPhoneのローテーションに対応できる
左右が逆に表示されるのは、xのスケールを-1にするしかないようだ
これは何故なのかわからないので、こういうものだと理解しておく
iPhoneの向きに合わせて、UIだけでなくGameObjectの向きも変わっている気がする...
Landscapeの時をデフォルトとして、Portraitの時に画面が拡大されている
Landscape/Portraitのどちらに変えても、PlaneのlocalScaleの値は変わらなかった
videoRotationAngileで紹介されているコードを反映すると、Landscape/Portraitのどちらでも正しく表示された
しかし、Portrait時は縦方向を1としているようで、横幅が入りきってない
Landscapeの時は -1.33:1 Portraitの時は -1:0.56 にすると良いのかもしれない?
ダメだった...
Camera.main.ViewportToWorldPointを使って画面を調整すればいい感じになる
Portrait時に画像が小さく表示されるのが難点
Safeareaを想定したものなのか??
画像が小さく表示される問題はあるが、まぁまぁいい感じに表示ができるようになった。
昨日の調査はカメラ画像も含めてテストすべきだった...orz
次の問題はこれ。
Unityのエディタで解像度を変えても、スケールがうまく変わらない
Input.DeviceOrientationを見てたから
MacだとDeviceOrientationはUnknownになるので、Screen.width, Screen.height から導出する
今回やってるはずの内容なのに...orz
無事解決。これに昨日のUIの調査結果を含めたアプリを一度作ってみよう。そのあと本体に組み込みだ。
やっぱ精度? 品質?上げるための仕事は時間がかかる。
解決したと思ったら、解決しなかった。主にPortraitモードの場合...。
解決方法がさっぱりわからないので、横方向でしっかり動くところを目標にして、先に進むことにする。
これまでの結果を統合
前と同じようにマスクをおみまいするところまでキタ!!!
と思ったら、画像の天地が逆になったり、顔の向きが逆になったり...orz
哀しいけどそこは置いといて、マスクの切り替えができるようにしてみた。
キツネのお面の大きさがイマイチである。
明日以降はまた地道な座標系の話だなぁ。
更なるカメラの調査
Camera.fieldOfView
垂直方向の視野。
iPhoneで確認したところ、Portrait/Landscape共に60だった。
Camera.pixelWidth, Camera.pixelHeight
スクリーンサイズと異なる値になっているのかと思ったが、同じだった
LandscapeとPortraitで同じサイズ(World上)のPlaneがPortraitだと拡大表示される
Unityカメラの位置
Landscape, Portraitで変化なし
Webカメラのローテーション
code:csharp
transform.rotation = webcamPlaneBaseRotation * Quaternion.AngleAxis(webcamTexture.videoRotationAngle, Vector3.up);
上記のrotationを制御するコードがなくなった場合
Landscape -> 正しく表示
Portrait -> 90度ずれている
Landscape(逆) -> 天地逆
Plane Local Scale(Changed): -0.5332668:1:-1.154701
鼻の位置のずれを直す
Gizmoというデバッグ用のオブジェクトを使って、算出した鼻の位置などを確認することにした。
カメラ中心は鼻の位置があっているが、カメラの中心から離れるほど鼻の位置がずれる。座標計算に誤りがあるのだろう。
パネルのZ位置は10f、マスクは9fの位置に表示している。1f分前にあるので、その分中心寄りに移動するはず。その分の計算が足りない。まずはここから直そう。
なんとなくあってきた。コードも整理してると、結局、座標の変換をひたすらやってる感じなので、変換のテストをしっかりするのが近道のような気がしてきた。
Quadを使って動画を表示する
動画や画像を表示するのは Plane ではなく Quad を使うらしい。ので入れ替え。
ついでに Landscape をデフォルトの方向としてレイアウトを調整することにした。
Quadにしたら何だか重くなった気がするけども。気のせい?
気のせいだった。カメラの解像度を 1280x960にしたせいだった。当面は640x480で十分(顔が認識できるから)なのでこれで行く。
UIをちょっとだけ変える
位置の修正が地味すぎて飽きてきたので、UIをちょっとだけ変えてみることに。
アーチーマクフィーのサイトの色を使って、ハトマスクのステッカーをアイコンにするとなんか面白い感じになってきた。
リリースするときはこのままじゃダメなので、修正忘れないようにしないとな。
写真を撮る
写真を撮れるようにしたい。ただ、顔の検出ができずマスクがうまくかぶれてなかったり、天地が逆になったりすることがあるので、シャッターを切った(ボタンを押した)後、これでいい? 画面を出して、OKならライブラリに保存という流れにしたい。
まずはModalのダイアログっぽいのを出すところから。
Modalダイアログとして作ったPanelのOnGUIで、GUI.ModalWindowを呼び出せば、モーダルウィンドウができる。
Modalにする場合は、CanvasのSort Orderを一番大きな値にしておくこと。
画像はQuadに表示しているTextureを、RawImageを使って表示すれば良さそう。
とりあえずModalを表示するときの引数として渡すことにする。
写真を保存したあと、Webカメラの処理を再開したい。このまま書き続けると、コードがとっちらかりすぎるので、一度整理する。
写真を撮るところまで
基本的な流れは以下のようになる。写真を保存という処理をクラスにして、そこで全ての処理を書いたほうがまとまりが良さそうな気がする。
"Now" ボタンをクリック
Webカメラを停止
画像を保存するダイアログを表示
顔の検出が上手く行かず、マスクが逆さになったり、表示されなかったりするので、このまま保存していいか聞く
保存する場合
写真をライブラリに保存
ダイアログを閉じる
Webカメラを再開
保存しない場合
ダイアログを閉じる
Webカメラを再開
クラスにまとめてひと段落。本当にこれでいいかよくわからないし、他のところとのズレもあるのだが、進めていく。
スクリーン?ショットを保存する
アセットで公開されているのでそちらを使うことにする。$20なり。とはいえあっという間に保存の処理ができた(PC上だけど)
ここまでで使ったお金。だいたい2万円くらい?
iPhoneでテスト。動いた!!!! カメラロールにも入ってる!!!!
処理速度の改善
ちょっと重い。プロファイリングを使ってどの処理が重いか見てみよう。
https://gyazo.com/d1467a2b5d6f7edeb9b5d4b39f691288
FaceLandmarkDetector.Detect が一番重い。それ以外はなんてことない。
解像度を下げると、顔を認識してくれないので、毎フレーム処理しないほうかなぁ。
解像度を800x600にすると、80msecくらいで処理が終わった。両方やることにしよう。
UIを見直す
とりあえずハトマスクをかぶせて、写真が撮れるようになったので、UIを見直してみよう。
普通の人が使うのは、ハトマスクをかぶせて、写真を撮る。マスクとカメラを変える。
開発用に、デバッグの情報を出せるようにしたい。
だから、写真撮るボタンと、デバッグ表示ボタンがあればいいはず。
ということで整理。この辺は、他のアプリを見習うことにしよう。
いらすとやさんの絵を使ってアイコンを作ってみたり。なんかちょっと変な感じ。
カメラを切り替えられるようにする
iPhoneにはBack/Frontのカメラがあるので、切り替えられるようにする。
Frontカメラを使うと、カメラ画像が表示されない。何かの計算が誤っているように思える。
以下のコードを除くと画像が表示されるようになったが、画像の天地が逆になってしまう...。
transform.rotation = webcamPlaneBaseRotation * Quaternion.AngleAxis(webcamTexture.videoRotationAngle, Vector3.up);
Webcamから取得した画像をそのまま保存してみて、何が起こっているのか理解した方が良さげ。
あぁ、面倒だなぁ...orz
Orientationに応じてボタンの位置の調整する
Quadを利用することで、Portraitで使える可能性が出てきたので、Orientationに応じてボタンの位置を調整してみる。
等間隔の配置だからLayoutを使えばいいのだけど、ボタンの大きさを統一しないといけない。
今回は、撮影ボタンだけ大きくしたいので、Grid Layoutを使わず、個別に位置調整をすることにした。
Orientationに応じて画像を編集する?
Webcamから得られる画像をそのまま表示すると以下のようになるっぽい。
Landscape Right
左右逆
Landscape Left
天地逆
左右逆
Portrait
右90度回転
左右逆
画像の色が薄い...
デバッグ用に表示しているRawImageの画像とQuadの画像を見比べると、明らかにQuadの方の色が薄い。
なぜだろうとあれこれいじってたら...。Lightのせいだった...orz
これを回避するには何をすればいいのか? もしかしてRawImageを使わないといけないのだろうか...。ヤバい。
というわけで、RawImageに画像を表示するように変更する...。明日頑張ろう。
カメラアプリの調査
RawImageに移行することに...。ついでに、もう少しカメラアプリを調べることにする。
iPhoneカメラ
縦方向固定、アイコンだけ方向に合わせて回転する
Microsoft Pix
縦方向固定、アイコンだけ方向に合わせて回転する
ただし、ハンドル?(タスクをアクセスするためにある画面下部の線みたいなの)は、方向に合わせて表示される
基本は方向固定で作るようだ。試しに、方向固定で作ってみたら、iPhoneカメラや、Microsoft Pixと同じ動作をした。
今までの苦労は一体...orz
各種エリアのサイズについて。
iPhoenカメラ
カメラの画像を表示する領域は、(縦方向で)横幅に合わせて、縦幅が伸びる
iPhone SE: 5cm x 6.7cm
iPhone 7: 5.85cm x 7.8cm
iPhone X: 6.2cm x 8.35cm
アスペクト比は 1.333 (カメラのアスペクト比と一緒だと思われる)
撮影ボタンのある領域は、iPhone SEが一番小さい
なんとなく iPhone SEを基準にして、iPhone 7, iPhone Xの表示領域が大きくなっているようにみえる
カメラ画像を表示する位置を、計算で求めるにはどうすればいいか??
カメラ画像を表示する領域を計算
横幅からアスペクト比1.33で計算する
下部の領域 (min) を確保
iPhone SEを最小とする
上部の領域を計算
全体 - (カメラ画像領域 + 下部領域(min))
上部の領域の高さが一定以上になった場合は、超えた分を下部領域の高さに加える
iPhone SE: 640x1136
カメラ画像領域: 640x851
下部領域: 209
6.7cm : 1.65cm = 851 : 209
上部領域: 76
1136 - (851 + 209) = 76
iPhone 7: 750x1334
カメラ画像領域: 750x998
上部領域: 87
下部領域: 249
1334 - (998 + 76) = 260
1.95cm : 7.8cm = 249 : 998
iPhone X: 1125x2436
カメラ画像領域: 1125x1496
上部領域: 243
(2436 - 1496) / 3.86 = 243
下部領域: 696
243 * 2.86 = 696
3.1cm : 8.35cm = 555 : 1496
上部、下部領域の比率もバラバラっぽいので、比率での計算は難しい。
カメラ画像領域: (解像度に合わせて計算)
下部領域: 209 (上限300まで)
上部領域: 76
で作ることにした。
FaceDetectorがおかしい
レイアウトについては問題なし。Webcamの画像表示も問題がなくなった。
が、顔検知がおかしい。
Landscape Leftの場合は正しく検知をするが、Portraitは検知しない。
Landscape Rightの場合は、検知結果を描画すると逆さになっている。
Landscape Leftは幅と高さと画像が一致している。
Portraitになると、幅と高さが入れ違った画像になっている。
Landscape Rightは幅と高さは一緒だが、おそらく画像が逆転している。
アプリでの見た目と、FaceDetectorに渡す画像の方向に食い違いが出ている気がする...。
Orientationに合わせてFaceDetectorに渡す画像の向きを調整
することで上記の問題は解消。全ての方向で顔を検出できるようになった。
マスクの表示 (Landscapeのみ)
検出結果を利用して、マスクを表示。まずは大きさと位置のみにした。
OpenCVとUnityの座標系、RectのPositionの違いを忘れてて、あわあわあわ。
なんとか表示できるようになった。
ので、次はリファクタリングから。
リファクタリング
テストのないリファクタリングとはと怒られそうなのである。
リファクタリングと言わなければよかったか。コードの整理をしてみた。
結構スッキリした気がする。
顔の向き判定の追加
以前のコードを追加して終了。実機でもうまく動いているようだ。
Portraitに対応する - サイズと位置
ここまで Landscape Leftのみを想定したコードだったので、それ以外にも対応させる。
リファクタリングが辛そうね。
ただ、まぁ座標計算さえしっかりできれば、他の箇所は変える必要がないはずなので、気は楽と言えば楽。
その次が写真を撮る。かなぁ。どっちを先にするか。ここまで粘ったんだから、Orientationをやろう。
いきなりつまづいた。以下のように変換が必要なもの、そのままがよいもの、そのまま+変換が必要なものの3種類あるので、単純に変換すればいいってわけではないことがわかった。
中心を求めるための位置情報 (変換が必要)
スケールを求めるためのサイズ情報 (そのままでよい)
向きを求めるための位置情報 (判定時はそのまま、表示時は変換が必要)
Portraitなら、求めた向きを左90度回転しないといけない
これらの調整は表示時に行うべきのような気もするので、そちらで頑張ることにしたら、必要な情報が足りてないので、顔検知のところで、Landscape Left用に変換した情報を生成することにした。
情報を一番持ってるところで処理をするのがいいのかもしれないけど、じゃ、なんの情報を持ってるのが適切なのかというと...。結局どこでも私はTestでFailになるんだけども、、でもやるんだよしかないんだよね。うん。 いろんな変更をいっぺんにしてるので、コミットログを書きづらい。
ここ「も」ダメなところなんだよねぇ。一歩ずつを忘れやすい。
Portraitに対応する - 回転
何をどうするのかよくわからない。勉強が必要。
4次元のマトリクスを使うと、回転、スケール、平行移動をいっぺんに表すことができる。
回転をシンプルに表現しようとしたのが Quaternion。で、Quaternionも演算が可能。
Portraitで算出した傾きを、Landscape Left基準にする。z軸に-90度回せばいいのかなと
landscapeLeftBased = baseQuaternion * Quaternion.Euler(0, 0, -90);
な感じのコードを書いたんだけど、うまく動かなかった。
顔が右に向くと、マスクが下に俯いてしまう。Y軸の回転が、X軸の回転に変換されているのか。
うーん。
面倒だけど、最初の向き推定を2回やったほうがいいかもな...。
やってみたけどうまくいかない。
初心に立ち返って、PNPとはなんぞやを勉強した方がいい気がしてきたのでちょっと読んでみる。
https://gyazo.com/574445afeb236111025724c548a0866a
基本はカメラの位置を推定するもの。
ワールド座標系: 右手
カメラ座標系: 左手
SolvePNPで出てくるベクトルはカメラの位置情報。なので、対象と向き合ってる形になるんだよなぁ。
https://gyazo.com/cb5c7eb366da1d459942bff432dbbdae
この記事だと、ワールド、カメラ共に右手座標。ImageはXが右方向に正、Yが下方向に正。
記事で
画像 (不明)
Xは右方向に正
Yは下方向に正
モデル (右手座標)
Xは右方向に正
Yは上方向に正
Zは手前に正
記事と同じように鼻の頭から線を書いてみた。下を向くと、線は上方向に出る。
上の記事を参考に、Rotation Vectorからオイラー角に変換、オイラー角からクォータニオン変換、クォータニオンをUnity座標系に変換、さらにオイラー角に変換をしてみた。
顔の向きと、オイラー角(x,y,z)の変化は対応していた。
が、マスクの角度を変えるためには、それぞれの軸に応じて変換が必要のようだ。
実測して、どの角度をどう変えれば良いのかを調査し、コーディング。理論からやるのは諦めた。
ということで、Portraitは完了。
写真の保存
前のをみながら作る。
Landscape Leftは簡単にできた。
Landscape Right, Portrait UpDownに対応する
1.5時間くらいでできた。ふぅ。
動作確認で iPhone 用にビルドしようとしたらエラーが。
新しくインポートしたCaptureAndSaveの設定をしてなかった...orz
写真は撮れた。が、方向が...。修正して完了。
カメラの切り替え
どうしようかなぁ...。なんとかできた。よくわからなかったところのコードが少しましになった。
マスクの切り替え
カメラと同じようにするか。完了。マスクは大きさが問題なのよねぇ...。
アイコンの設定
アジャパンのアレを使うことにする。
Apple Developer Programに参加する
いいところまで来てるのでProgramに参加することにする。
間違って2回支払いしてしまったので、電話をするなど...orz
うっかりミスなのは認めるんだけども、アカウントの画面に注文状況反映しておいてほしなぁ。
フォームでの問い合わせのようなので、そちらに2回支払いをした旨をかいて送ってみた。さてどうなるだろうか?
デバイスの方向に合わせてボタンを回転させる
サクッとできた。すごい。
iOS証明書&Profile
証明書はこちら。
Profileはこの辺を見て、まずはAdHocから。
AdHocだとXCodeからの転送&実行ができなかった。
Developmentに変更してOKになった。
アーチーマクフィーに相談する
マスクの件で。
こんにちは。私はあなたのところのハトマスクが大好きです。
私はモバイルアプリを作っています。カメラに写った人にハトマスクをかぶせるアプリです。
ハトマスクはあなたのところのマスクをみながら作りました。
私はこのアプリをAppStoreに公開してみんなに使ってほしいと考えています。
このマスクも一緒に 公開してよろしいでしょうか?
許可をいただくために私にできることがあれば、できる限り協力したいと考えています。
こんな感じかなぁ?
Contact Usから以下の文面で送ってみた。返事が来るといいんだけどなぁ...。ヤバい変なやつからメッセージが来てるくらいだよなぁ。
Hello.
I like Archie McPhee's pigeon mask. I bought 10 masks and take photos with friends!
And I made mobile app to put pigeon mask on person are displayed in camera.
I make this pigeon mask 3d model refer to Archie McPhee's mask.
Pigeon Mask in My Mobile App
I would like to publish this mobile app with pigeon mask to App Store.
What should I do to use your pigeon mask design?
品質を上げるために
今は超雑なので、以下のようなことをしながら、アプリとしての精度を高めていきたい。最終的には回転ベクトルだけでなく、並進ベクトルを使ってマスクを移動させないといけないんだろうなぁ。
マスクの位置がずれている
今の所うまくいってない。→ 鼻の位置はなんとか。
マスクから顔が見えてる
とりあえず置いとく
マスクがチラチラ揺らいでしまう
とりあえず置いとく
光源の位置を予測して、マスクにもそれっぽい光を当てたい
Safeareaを計算に入れていない
UIの領域を増やせばいい気もする
Portraitの時: y軸、Landscapeの時: x軸のみ考慮すればいいと思う
デバッグモードが欲しい
位置計算に利用している情報や、顔検知の情報などをプロットした動画など、デバッグに必要な情報が表示されるモードが欲しい
UI、アイコンを見直す
今はアーチーマクフィーのサイトの色とか使ってるのであんまよくない気がする
アイコンはアジャパンのステッカーを使ってるので、これまた直さねば。
写真にステッカーを貼り付ける
Hatomask Enabledステッカーを貼り付けるのだ
画面縦向きのロックをしていると、PortaitやLandscape Rightで顔認識しない
ボタン自体が回転してないから、UnityでもDeviceOrientationの変化を検知できないらしい。
どうすればいいんだろう?
Screen.Orientationを使うのかもしれない?
UnityのScreen.Orientationはアプリの向きを知るためのものだった。
DeviceMotion -> ジャイロスコープ? の値を検知して判定する方法があるんだそうな。
方向を知るためだけに、ジャイロスコープの値を覗くのもなぁ。
Twitterに投稿したい
やっぱねぇ。
マスクの天地が逆になっている
強引に解決 (技術的負債)
カメラ画像が左右反転している
ほぼ解決できそう
モバイルアプリで縦横どの方向でも対応したい
モバイルアプリでカメラを選べるようにしたい
お面やマスクを切り替えられるようにしたい
ハトマスクのモデルの精度を高めたい
ひとまず高くなった。あとは地道な改善....。テクスチャを貼ったりするのかなぁ。
カメラを縦に逆さにするとおかしくなる
レイアウトが変わったことを検知できない感じ?
対応しないことにする → 対応した
アスペクト比が1.33以外の端末で表示がおかしくなる
例えばiPhone5のように1.5になった場合とか
でもiPhoneXなら大丈夫のようだ。何かおかしい。
Reference Resolutionを加味したサイズ計算をしないといけない気もするが...。
Quadにしたら解決した感じ? (なぜそうなるのかは理解不能...)
Planeはスケールがcubeなどの10倍あるのでその辺が関係してそうな気もする...。
→ 解決
Portraitの場合、カメラ画像が約1.5倍に拡大されてしまう
カメラ画像を表示しているPlaneの大きさが約1.5倍になっている感じ
どういう理屈でこうなるのかさっぱりわからない
とりあえず横方向でうまく動くところを目標とする
→ 解決
OrientationをLandscape Leftに固定して、カメラ画像を回転させる方向で対応した