フォトグラメトリ、3Dスキャナ、最近のipad proに搭載されているLIDARやIntelのRealsenseなどの深度(Depth)センサを用いたRGBDカメラなど、撮影した動画像(+Depth)データから3Dデータへ変換する試みが行われています
AR、VR、ゲーム開発などで用いる3Dモデル作成への応用やCADデータとしての利用など今後も様々な分野での活用が期待される技術です
今回は深度センサや3Dスキャナなどのデバイスを使わずに、シンプルにスマホで撮影した動画から撮影された物体の3Dデータを生成するまでの方法を説明します
Depthデータがない分、推定誤差や様々な影響によるノイズがあるため、Depthセンサや3Dスキャナを用いた方法よりは精度が落ちますが、動画から手軽にできるというところがメリットです
今後ノイズを減らすDenoisingなどの研究が進んで、精度を上げられるようになるか、Depthセンサがすべてのスマホカメラに搭載されるようになるのかはわかりませんが3次元データを扱えるようになっておくというのは今後より重要になってくるのではないでしょうか?
実行環境
私が実行した環境は下記の通りですが、PCについてはこれと同じである必要はありません
- PC
- NVIDIA GeForce 1070
- OS
- Ubuntu 18.04LTS
- ライブラリ
- git
- ffmpeg
- libjpeg
- libpng
- libtiff
- openGL
- qt5
- meshlag
必要なライブラリをインストールしよう
下記のとおりライブラリをインストールします
$ sudo apt-get install git ffmpeg libjpeg-dev libpng-dev libtiff-dev freeglut3-dev libglew1.5-dev qtbase5-dev qttools5-dev-tools qt5-default meshlab
動画データを準備しよう
動画から3Dデータを生成するためには様々な角度から動画を撮影することが重要です
動画の異なるフレーム間で同じ特徴をもつ点を物体における同じ点であるとみなして、深度を推定することになります
そのため、ゆっくりと物体の周りを球面状にカメラを動かしつついろんな角度を捉えて撮影することになります
撮影する物体を球(Sphere)の中心と考えて、その中心をとらえつつ球面状にカメラを動かしながら物体のいろんな角度を撮影するというイメージですね
あまり長すぎると解析に時間がかかるので、30秒から長くても1分くらいの動画にすることをおすすめします
今回はtest.mp4という名前にした想定で手順を説明していきますので、適宜読み替えてください
私は今回は「ゼロから作るDeep Learning」本を机の上において撮影した動画を使います

MVEをインストールしよう
MVEとはMulti-View Environmentの略で、Structure from Motion, Multi-View Stereo and Surface Reconstructionなどの様々な機能を持つ強力なソフトウェアです
それぞれの細かい解説は今回は割愛しますが、複数視点でのデータを扱って様々な3Dデータ処理を施すような機能を有するとてもありがたいものと理解しておいてもらえれば良いです
今回はこのMVEをがっつり活用させていただきます
下記がgithubになりますので興味がある方はReadmeやコードなどを見てみてください
それでは早速githubをクローンしてMVEをインストールしましょう
$ git clone https://github.com/simonfuhrmann/mve.git
$ cd mve
$ make -j8
今後の作業のために下記のディレクトリを作っておきましょう
$ mkdir inputs
$ mkdir inputs/images
$ mkdir inputs/scenes
先ほど撮影した動画は、ここで作成したmve/inputsディレクトリ配下に配置してください
動画を画像に切り分けよう
MVEを使って解析をするにはいったん動画を画像に切り分ける必要があります
そこでffmpegというソフトウェアを使用します
$ ffpmeg -i inputs/[撮影した動画ファイル名] -ss [対象とする動画の開始点(秒)] -t [対象とする動画の終了点(秒)] -r [1秒間に何フレーム分の画像を切り出すかの枚数] -f image2 inputs/images/%06d.jpg
具体的には私が試験用に撮影した動画はだいたい22秒の動画だったので、下記のように実行しました
$ ffmpeg -i inputs/test.mp4 -ss 0 -t 22 -r 8 -f image2 inputs/images/%06d.jpg
rオプションのところは多くした方が精度は上がると思いますが、その分解析に時間がかかるのでトレードオフを考えて設定してください
こうすると000001.jpgからはじまる画像ファイルがinputs/images配下に大量に出力されます
実際にみてみると動画から生成された画像であることがわかります
ちなみに逆に連番の画像から動画を生成する方法は下記で行えます
$ ffmpeg -r 30 -i %6d.jpeg test.mp4
pngファイルからの動画生成の場合はこちらです
$ ffmpeg -r 30 -i %6d.png -c:v libx264 -pix_fmt yuv420p test.mp4
MVEを用いて3Dデータを生成しよう
MVEのインストールと画像の生成が上手くいっていればmveディレクトリ上で下記のコマンドを順に実行すれば3Dデータが生成されます
$ ./apps/makescene/makescene -i inputs/images/ inputs/scenes/
$ ./apps/sfmrecon/sfmrecon inputs/scenes/
$ ./apps/dmrecon/dmrecon -s2 inputs/scenes/
$ ./apps/scene2pset/scene2pset -F2 inputs/scenes inputs/scenes/pset-L2.ply
$ ./apps/fssrecon/fssrecon inputs/scenes/pset-L2.ply inputs/scenes/surface-L2.ply
$ ./apps/meshclean/meshclean -t10 inputs/scenes/surface-L2.ply inputs/scenes/surface-L2-clean.ply
やっている処理としては下記のようなイメージになります

それぞれmve/inputs/scenes配下にpset-L2.ply, surface-L2.ply, surface-L2-clean.plyという3つのplyファイルが出力されていれば成功です
- pset-L2.plyは点群データをいわれる、Objectの頂点情報を色付きで大量に保持したものです
- surface-L2.plyは頂点情報から少し面を推定して処理を施したものです
- surface-L2-clean.plyはsurface-L2.plyをさらにきれいになるように処理を施したものです
Meshlabで3Dデータをみてみよう
最初にインストールしておいたmeshlabを起動します
$ meshlab &
surface-L2-clean.plyが見栄え的には一番わかりやすいので、そのファイルをmeshlabにドラッグ&ドロップすれば、例えば下記のように3Dデータをみることができます

結果をいろんな角度からみてみましょう



最後に
やはりDepthデータなしでやった場合ではそれなりにノイズが多く、かなり真面目にDenosing(ノイズを除去する処理)を頑張らないと、良い結果を得るのは難しいのだなと感じました
また関係ないものが動画に映り込むとそれが結果に影響するので、そのあたりも難しいと感じました
今回の結果では本の表紙の白い部分などが完全に情報が欠けてしまっています
これは、画像のみからだと白部分の特徴を捉えるのがむずかしく、その部分は何も存在しないと判断されてしまうからです
今後はDepthセンサなども使ってどこまできれいになるか試したり、Denoisingの手法を調べてみたりしようかと思います
コメント