ストリーム配信した動画でLSD-SLAM
今回はAndroid,iPhoneから動画をストリーム配信、PCで受信しLSD-SLAMを実行します。
ストリーム配信用アプリ
- Androidの場合
Androidでは、VXG RTSP Server (https://play.google.com/store/apps/details?id=veg.mediacapture.sdk.test.server&hl=ja)というアプリを使いました。
- iPhoneの場合
iPhoneでは、Live-Reporter(https://apps.apple.com/jp/app/live-reporter-監視カメラ/id996017825)というアプリを使いました。
スマホをRTSP serverにできるアプリならなんでも良いのですが、fpsや動画サイズなど細かい設定が行えるものを推奨します。fpsは高め(サンプル動画は50fps)で、動画の解像度は640x480が良いみたいです。上記のアプリではどちらの場合も、アプリ内設定で解像度は640x480でキーフレームは30fpsにしました。
ストリーム受信用パッケージ
PCのROS上で動画を受信する必要があるため、ROSのvideo_stream_opencvを使いました。gitからソースコードをとってきてcatkin_makeでビルドする方法もあるようですが、自分の環境ではビルドでエラーが出ました。そのためaptを使って以下のコマンドで入れます。以下のコマンドのindigoとなっている部分はPCにインストールしたROSのバージョンによって適宜変更してください。
$ sudo apt install ros-indigo-video-stream-opencv
備忘録として書きますが、もしgitからソースコードを落としてきてビルドに失敗していた場合は、一度パッケージディレクトリ内のvideo_stream_opencvのファイルを削除してからaptを使って入れます。実行した際にaptで入れた方ではなくインストールに失敗した方が実行されてエラーが出ます。
次にvideo_stream_opencvのlaunchファイルも作成しておきます。
rosrunでもノードは起動できますが、ノードに対して細かい設定を行う際はコマンドが長くなりすぎて大変です。そういう場合にlaunchファイルの中に細かい設定を書くことで簡単にノードを起動できます。あとlaunchファイルは複数のノードを一斉に起動できたりしますが、ここではvideo_stream_opencvのノードに対して、細かい設定を行うために用います。
//ファイル作成(ファイル名や作成する場所は自由) $ touch ~/stream_receive.launch //テキストエディタでファイルを開く $ gedit ~/stream_receive.launch
一旦スマホ側でストリーム配信を開始して受信用アドレスを確認します。例として192.168.x.x:ppp(ipAdress:port)とするとlaunchファイルは以下のようになります。コピペしてアドレスを書き換えて保存して下さい。
<?xml version="1.0"?> <launch> <include file="$(find video_stream_opencv)/launch/camera.launch" > <!-- node name and ros graph name --> <arg name="camera_name" value="rtsp" /> <arg name="video_stream_provider" value="rtsp://192.168.x.x:ppp" /> <arg name="buffer_queue_size" value="1000" /> <arg name="fps" value="30" /> <arg name="frame_id" value="rtsp_frame" /> <arg name="camera_info_url" value="" /> <arg name="flip_horizontal" value="false" /> <arg name="flip_vertical" value="false" /> <arg name="visualize" value="false" /> </include> </launch>
カメラのキャリブレーション用パッケージ
LSD-SLAMでは広角レンズを使ってもSLAMができるようで、動画の歪みを補正する必要があります。スマホの動画には歪みはありませんが、それでもキャリブレーションファイルが必要です。ROSのcamera_calibrationを使います。
$ sudo apt-get install -y ros-indigo-camera-calibration
キャリブレーションファイルの作成
キャリブレーション用の画像を印刷して、平らな場所に貼ります。スマホでストリーム配信を開始してから、以下を実行します。
$ roslaunch ~/stream_receive.launch $ rosrun camera_calibration cameracalibrator.py --size 8x6 --square 0.025 image:=/rtsp/image_raw
二行目で size 8x6 とあるのはこのように認識されるからです。また square 0.025 は一辺2.5cmを表します。
距離や角度を変えて印刷した画像を撮影します。1分程度するとCalibrateボタンが押せます。処理が終わるまでウィンドウがフリーズしますが、しばらく待つとSaveボタンが押せます。出来たファイルの場所は、
/tmp/calibrationdata.tar.gz
です。保存後は各ターミナルをCtrl+cで終了し、ファイルを解凍して中にあるosm.yamlを開きます。このファイルを見ながらcfgファイルを作成していきます。
キャリブレーションのためには、LSD-SLAM実行時にcfgファイルを参照するか、video_stream_opencv実行時にyamlファイルを参照してLSD-SLAMにカメラデータを流すかのどちらかをします。今回はcfgファイルを作成します。LSD-SLAMがcfgファイルを参照する場所は
~/rosbuild_ws/lsd_slam/lsd_slam_core/calib/
にあるcfgファイルなので、以下を実行します。
$ touch ~/rosbuild_ws/lsd_slam/lsd_slam_core/calib/mobile_stream.cfg $ gedit ~/rosbuild_ws/lsd_slam/lsd_slam_core/calib/mobile_stream.cfg
yamlファイルとcfgファイルのフォーマットを記述するので、以下を参考にするのと
~/rosbuild_ws/lsd_slam/lsd_slam_core/calib/
の中に最初からあるcfgファイルも参考にして新しいcfgファイルを作成してください。
cfgファイルのフォーマット
fx fy cx cy k1 k2 p1 p2 inputWidth inputHeight crop outputWidth outputHeight
yamlファイルのフォーマット(抜粋)
camera_matrix: rows: 3 cols: 3 data: [fx , 0, cx, 0, fy, cy, 0, 0, 1] distortion_coefficients: rows: 1 cols: 5 data: [k1, k2, p1, p2, k3]
ORB_SLAMのキャリブレーションファイルのフォーマットも以下の図に示します。