关于VisualSfM的更多内容
组合多个模型(What if VisualSFM produces multiple models?):
按照上述步骤进行稀疏重建后,理论上可以得到很好的模型。如果结果产生了多个模型,要想把多个模型合成成一个,点击菜单中的“SfM->More Functions->Merge Sparse Models”。log信息中会提示你各个模型中有多少共享的特征点,如果特征点数量小于程序默认的最小值,则不会进行模型融合。编辑VisualSfM路径下的nv.ini文件,可以修改程序要求的最小值“param_model_merge_min_matches ”(默认是100),把该参数改成小于模型间共享特征点数量的一个数(不宜小于10),再执行“SfM->More Functions->Merge Sparse Models”应该就可以融合有共享特征的模型了。如果模型之间一个共享特征都没有,那就只能从头来了。
稠密重建(Dense reconstruction):
在稀疏重建结束后,点击CMVS可以对模型进行稠密重建。CMVS会对样本进行聚类,再根据每一个聚类生成一个ply模型文件,生成时间较长,需要耐心等待。
中国农业大学东校区体育馆的稠密重建示例如下:
中国农业大学工学院的稠密重建示例如下:
输出格式(The output format: N-View Match (NVM) & PLY):
NVM
理解NVM文件最简单的方法就是用TXT文本文件或Sublime Text打开,就可以直观的看到其组织方式。
“
NVM_V3
2
et007.jpg 660.197875977 0.998820995653 0.0275106001103 -0.0259087505623 0.0304716951484 0 0 0 0 0
et008.jpg 660.197875977 0.160476730087 -0.112869970691 -0.125560022607 -0.972492485698 -0.380315317109 -0.867596366593 0.320369513256 0 0
1111
-0.16864857602 0.290092727826 3.09711024403 231 201 214 2 0 0 -72.4277801514 22.055480957 1 3 158.19152832 -77.7308959961
…………
”
2代表2张照片,即下面2行,每一行是一个照片的参数。参数按空格分割依次是 0
然后1111代表有1111个点,每一行是一个点的信息,参数按空格分割依次是
一般我们只关心XYZ和RGB,取前6维数据即可。
util.h文件提供了C++版本的nvm文件解析方法。我自己用python写了一个。其实就是按行解析,每一行以空格' '作为分隔符,就可以得到如下文件,因为pandas存储CSV是无序的,所以列没有按顺序保存。
其中dataframe是每一张照片对应的相机参数,坐标(XYZ)和四元数(WPQR)如下:
point_dataframe是点云文件,每一行对应一个点的颜色(RGB)和坐标(XYZ)如下:
PLY
是一种电脑档案格式,全名为多边形档案(Polygon File Format)或斯坦福三角形档案(Stanford Triangle Format)。
稠密重建的结果会保存成PLY文件格式。它的具体格式如下:
“
ply
format ascii 1.0
element vertex 257684
property float x
property float y
property float z
property float nx
property float ny
property float nz
property uchar diffuse_red
property uchar diffuse_green
property uchar diffuse_blue
end_header
-0.721213 -2.01925 2.6344 0.130806 0.0792633 -0.988234 205 214 218
-0.991508 -1.99528 2.58972 0.163215 0.0746168 -0.983765 195 202 202
…………
”
前门是头文件,property描述了头文件之后的每一列的特征。也就是说,在end_header之后,按空格分隔,这9个数字依次代表点的坐标XYZ,法向量nx、ny、nz,和像素RGB。
这样只需要按类似方法解析就可以使用了。
坐标系统(coordinate system):
Documentation原文说”As for the image coordinate system, X-axis points right, and Y-axis points downward, so Z-axis points forward.”
即X轴指右,Y轴指下,Z轴指前。这和openGL与Unity的坐标系统都不同,使用时注意坐标矫正。
用Unity游戏引擎进行可视化(Visualization with Unity):
Unity的Asset store上有很多点云库,我随便下载了一个。
把我们的点云数据转成了它要的off文件,就可以使用在unity里查看点云了。需要注意的是,要把读取坐标的代码修改一下,读取坐标y的时候要乘以-1,这样显示结果才是正确的。
off文件具体形式如下:
“
COFF
20733 0 0
0.253539073845 -0.100282664831 4.76099905695 20 24 12 255
1.53241726658 -2.33590458129 5.98022141801 62 58 52 255
…………
”
第二行表示点的数量
后面的参数按行分割就是每一个点,按空格分割是XYZ和RGB。
我们也可以对相机位姿进行可视化,可以看到可上图结果是差不多的。需要注意的是相机的y坐标和四元数Q也要乘以-1。
最后用unity自带相机对重建结果进行可视化验证。把相机坐标和角度赋值给unity相机以后,调整unity相机的Fov(field of view),我这里是50。然后以当前位姿拍摄的照片作为相机背景,即可得到如下效果。