Android手机上图像和IMU数据采集的方法
采用开源库 https://github.com/DavidGillsjo/VideoIMUCapture-Android可同时采集图像和IMU数据并提供了标定脚本,具体的标定方法可参考项目下的calibration文件夹中的README。
第一步:手机上采集数据并将数据导入到电脑
运行APP采集的数据在手机上的存储路径为/sdcard/Android/data/se.lth.math.videoimucapture/files/YYYY_MM_DD_hh_mm_ss
可以通过adb命令将数据从手机拷贝到pc
adb pull /sdcard/Android/data/se.lth.math.videoimucapture/files/2022_03_27_09_34_31
录制的数据共生成2个文件
其中video_meta.pb3是protobuff存储格式,其中包含了IMU的数据
第二步:使用运行Docker容器处理采集的数据
我用的是Ubuntu18.04装的Docker,在calibration文件夹下运行命令
SUDO=1 DATA=<my-data-path> ./run_dockerhub.sh
<my-data-path>是电脑上存储采集数据的目录,进入Docker容器后,默认在calibration目录
这里的calibration目录是docker中的,里面是用于处理采集的数据的Python脚本,其实这个docker容器是配置好了kalibr库,就不用我们自己去编译安装这个库了。
第三步:标定相机
首先要处理一下采集到的数据,将数据转换为kalibr可处理的数据,kalibr是运行在ros中的,其实就是将数据转换为rosbag。
python data2statistics.py /host_home/<path-to-recording>/video_meta.pb3
/host_home/<path-to-recording>代表的是宿主的数据存储路径,也就是我们Ubuntu系统中的路径。host_home代表Ubuntu的home路径。
比如我把数据放到了Ubuntu中的~/VideoIMUCapture-Android/calibration/cc3下,那在docker中执行的命令为
这里--tag-size表示我们自己打印的Apritag后,用尺子测量的一个二维码大小单位是m,--subsample为从.mp4文件中采样图片间隔,30表示每隔30帧采样一张。
这个脚本执行完后,如上图,会在数据存储的目录生成一个kalibr目录,用于存储处理好的数据。
下一步我们进入到kalibr目录,执行标定命令
完成后,会生成camchain-kalibr.yaml文件表示标定完成,result-cam-kalibr.txt是标定的结果,其中保存了误差等数据,report-cam-kalibr.pdf是生成的统计图
第四步:标定IMU
由于IMU的加速度计和陀螺仪有噪声和游走噪声,需要单独的标定,目前都是采用imu_utils库来标定。
首先我们要在Ubuntu中安装ros,并编译imu_utils。
1、这里我们用另一个App单独采集IMU数据https://github.com/sunset768541/mobile-ar-sensor-logger。
采集的数据存储在手机的/sdcard/Android/data/edu.osu.pcv.marslogger/files/data/路径
存储的格式为
2、安装ros 可参考https://zhuanlan.zhihu.com/p/397594162文章
安装imu_utils可参考https://blog.csdn.net/learning_tortosie/article/details/102415313#commentBox 文章
3、修改一下采集到的gro_accel.csv的第一行为,并改成imu0.csv
4、将imu0.csv转换为ros.bag 可参考https://blog.csdn.net/hltt3838/article/details/116064390
利用kalibr_bagcreater 因为我们在Docker中安装了kalibr,所以我们进入docker中执行
5、创建launch文件
<launch>
<node pkg="imu_utils" type="imu_an" name="imu_an" output="screen">
<param name="imu_topic" type="string" value= "/imu0"/>
<param name="imu_name" type="string" value= "meizu18"/>
<param name="data_save_path" type="string" value= "$(find imu_utils)/data/"/>
<param name="max_time_min" type="int" value= "11"/>
<param name="max_cluster" type="int" value= "100"/>
</node>
</launch>
imu_name可以自定义,比如我的是meizu18
max_time_min表示采集imu的数据的时间,建议2个小时,单位是分钟,我这里只采集的11分钟
6、启动标定 可参考https://blog.csdn.net/sinat_25923849/article/details/107867407
roslaunch imu_utils android.launch
rosbag play imu.bag
最好先 source imu_utils path /devel/setup.bash
roslaunch启动程序,rosbag play是播放录制的数据,可以-r 200设置200倍播放,当处理完后。
在imu_utils中生成了标定文件
6、注意如果调用ros命令时报错,没有命令 可以运行source /opt/ros/里面有个source.bash
第5步:相机和IMU融合标定
同样,根据VideoIMUCapture-Android/库的calibration下的README.md Calibrate IMU and camera部分
首先通过python data2kalibr.py 处理记录的数据,这里 --kalibr-calibration指向我们在相机标定步骤生成的标定文件
在生成的kalibr文件中执行,记得要把我们之前标定的IMU数据拷贝到imu.yaml中
这一步完成后,就生成了标定结果
备注
注意标定相机和 相机IMU融合标定的录制数据方式不同,
单独标定相机,是保持相机不动,移动Apritag。
相机和IMU融合标定是ApilTag不动,按照https://github.com/ethz-asl/kalibr/wiki/camera-imu-calibration 给的方式采集数据。
重要:如果采集标定的数据误差大于0.5,可能是采集的图像质量不够好,注意采集图像的时候要慢慢移动,保证每个图片都清晰,光线好,Apritag要平整,尽量贴在硬纸板上。
ps:我开始的误差是0.55,在重新采集图片后,误差降低到了0.137。一般0.1-0.2表示标定结果优秀。