由于苹果手机自带雷达(pro),因此在进行三维重建过程中,可以借助苹果手机,实现对深度图和rgb图像的采集,再根据手机相机的内参和姿态,实现三维重建。
RGBD数据采集
苹果手机的开发API是ARkit,这意味着如果想获取苹果手机拍摄的深度数据和RGB数据等,需要通过它的api进行开发,调用手机的相机接口,进行获取数据,显然这个流程太麻烦且没有必要,因此有人开发了相关的app,只需要通过app进行拍摄,就可以获取一份数据包,然后导出到电脑即可。
- 相关程序app介绍:链接
- 操作也很简单,打开录制,对着物体录制一段视频,然后内存里面就会存储一个文件夹,文件夹名称随机,主要内容包括:
- confidence:置信度文件夹,记录每一帧深度图的置信度信息,png格式
- depth:深度图文件夹,记录每一帧深度数据
- camera_matrix.csv: 相机内参
- imu.csv: 记录相机移动的数据
- rgb.mpg: 录制的彩色视频,即rgb数据
进行三维重建
使用app提供方法
该作者同样提供了相关的python处理代码:链接,使用方式也比较简单,只需要将采集的数据文件夹放在项目根目录下,输入命令: python stray_visualize.py <path-to-dataset>
即可显示,通过支持查看点云、重建、相机坐标系等参数
总结
项目使用tsdf的方式进行三维重建,借助open3D实现可视化和模型生成,其首先根据置信度将深度图进行筛选,小于限定置信度的深度值设置为0,其次将视频处理成rgb帧,融合深度图里,借助相机内参和姿态进行三维重建
tsdf重建
上一种方式也是通过tsdf进行重建,但是是借助open3D来实现,tsdf-fusion-python 是一个比较直观的实现tsdf算法的程序,其主要思想参考:链接
由于tsdf-fusion-python 可以借助gpu进行运算,这意味着对于处理大批量的场景和数据,其运行速度可以远远小于第一种方式,因此,如果需要调用gpu,只需要配置cuda,程序默认会查看能否调用gpu,当然如果不支持gpu方式,那么通过也可以用cpu跑
问题是,tsdf-fusion-python 程序支持的数据格式和第一种方式并不一致,这意味着需要写脚本将采集到的rgbd数据做一层转换,处理成该程序支持的格式,主要流程如下:
def deal_camera_data(flags,data):
out_path = "CameraData"
if not os.path.exists(out_path):
os.makedirs(out_path)
#获取相机内参和视频读取
intrinsics = get_intrinsics(data['intrinsics'])
# 保存相机内参
intrinsics_filename = os.path.join(out_path, 'camera-intrinsics.txt')
np.savetxt(intrinsics_filename, intrinsics.intrinsic_matrix, fmt='%.6f')
rgb_path = os.path.join(flags.path,'rgb.mp4')
video = skvideo.io.vreader(rgb_path)
for i ,(T_WC,rgb) in enumerate(zip(data['poses'],video)):
print(f"Integrating frame {i:06}",end='\r')
#处理深度图
confidence = load_confidence(os.path.join(flags.path, 'confidence', f'{i:06}.png'))
depth_path = data['depth_frames'][i]
depth_mm = np.array(Image.open(depth_path))
#置信度过滤
depth_mm[confidence<2] = 0.0
depth_mm = depth_mm.astype(np.uint16)
# depth = load_depth(depth_path)
o3d.io.write_image(os.path.join(out_path,f"frame-{i:06d}.depth.png"),o3d.geometry.Image(depth_mm))
#处理rgb图像
rgb = Image.fromarray(rgb)
rgb = rgb.resize((DEPTH_WIDTH,DEPTH_HEIGHT))
rgb = np.array(rgb)
#保存rgb图像
rgb_filename = os.path.join(out_path,f"frame-{i:06d}.color.jpg")
Image.fromarray(rgb).save(rgb_filename)
# 保存相机姿态
pose_filename = os.path.join(out_path, f"frame-{i:06d}.pose.txt")
np.savetxt(pose_filename, T_WC, fmt='%.6f')
bundlefusion重建
同样需要对原始采集的数据做处理,其难点在于程序环境的搭建,源码
主要参考网上vs2017+cuda11的配置方法,然后遇到问题去源码里面的issues找相关的问题描述和解决办法即可,但是最终我的建模效果没有比第二种好多少
具体环境配置就不描述了,如果遇到问题可以留言交流