ストリーム配信した動画でLSD-SLAM

今回はAndroid,iPhoneから動画をストリーム配信、PCで受信しLSD-SLAMを実行します。

ストリーム配信用アプリ

Androidでは、VXG RTSP Server (https://play.google.com/store/apps/details?id=veg.mediacapture.sdk.test.server&hl=ja)というアプリを使いました。

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を表します。

calibration_image(画像が表示で着ませんでした)
calibration

距離や角度を変えて印刷した画像を撮影します。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のキャリブレーションファイルのフォーマットも以下の図に示します。

f:id:shibuya_shogo:20210309205411p:plain
orb_slam calibration

LSD-SLAMの実行

いよいよ準備完了です。
スマホでストリーム配信を行ってから以下を実行します。

$ roscore
$ rosrun lsd_slam_viewer viewer
$ roslaunch ~/stream_receive.launch
$ rosrun lsd_slam_core live_slam image:=/rtsp2/image_raw _calib:=mobile_stream.cfg

今度研究室に行ったときに実行中の動画を載せます。