關于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。然后以當前位姿拍攝的照片作為相機背景,即可得到如下效果。