玩玩三維重建
版權聲明:本文系本站作者自己翻譯整理,歡迎轉載,但轉載請以超鏈接形式註明文章來源(planckscale.info)、作者信息和本聲明,否則將追究法律責任。
我們在實時三維重建方面的工作今年已經密集展開。或許不久後某一天,你會在本站看到帶有SLAM(即時定位與地圖構建)功能的四軸飛行器,或者讓你在書桌上打一場現代戰爭的增強現實應用。在敲鑼打鼓歡天喜地亮出我們自己的三維重建實現前,先拿別人的東西給大家打打牙祭。
中科大劉利剛教授的3D建模軟件與處理軟件簡介介紹了N多實用的3D相關軟件。而基於照片的快速建模軟件並不多,之前玩過123D Catch,很贊。圍着你要建模的物體拍攝一圈,用123D Catch加載拍攝的圖像,經過其強大的處理能力,生成具有紋理的3D模型。下圖是我重建的我的蒙奇奇。你要做的只是拍照、上傳、等待而已,相當簡單。
但是123D Catch也存在一些侷限,完全的黑盒子,對重建過程沒有任何操控力。
要想了解從照片如何一步步重建出三維模型,並能操控某些過程,可用的免費開源軟件也不少,較常用的是VisualSFM和Meshlab:
第一步:VisualSFM
VisualSFM軟件允許我們上傳一系列圖像,它從這些圖像中找到每一個圖像的特定特徵,利用這些特徵信息重建出3D模型的稀疏點雲,而後還可進行稠密點雲重建。
輸入:圍着要重建對象拍攝的一系列照片;
輸出:一個 .out文件,存儲着每個相機的位置及重建出的稀疏點雲;
一個.ply文件,存儲着由稀疏點雲重建出的稠密點雲。
第二步:Meshlab
可用Meshlab對3D網格/點雲做各種操作。輸入VisualSFM的生成文件,Meshlab通過一系列操作可創建出包含紋理的、乾淨的、高分辨率的網格,並自動計算UV映射及創建紋理圖像。
輸入:VisualSFM的生成文件,.out文件和list.txt文件(存儲照片序列); 以及.ply文件;
輸出:一個.obj文件,3D模型的網格;
一個.png文件,任意大小的紋理圖;
完整的流程見下圖:
第一步:運行VisualSFM
1. 輸入一系列圖片
拍照注意事項:切忌不要站在原地,僅轉動身體去拍:相機共中心能拼接全景,但是給不出三維重建的深度信息。要以待重建的對象爲中心,圍着它每轉10-20度拍一張,這樣轉一圈,有不同高度信息更好。VisualSFM沒有照片數量限制,照片越多,重建出的細節越豐富,但重建過程花費時間越長。
2. 特徵檢測及匹配
因照片可能存在旋轉、縮放或亮度變化,此過程利用SIFT算法提取、描述特徵,用 RANSAC算法過濾掉誤匹配。此過程亦可利用GPU加速。工作狀態實時顯示在側邊的log窗口。
3. 利用SFM進行稀疏3D重建
利用 SFM 方法,通過迭代求解出相機參數和三維點座標。即重建出3D模型的稀疏點雲。若有“bad”相機(位置錯誤或朝向錯誤),結合工具欄上的“3+”按鈕和手型按鈕即可刪除之,使結果更準確。
4. 利用 CMVS/PMVS 進行稠密3D重建
CMVS/PMVS需自己下載,編譯,也可直接下載exe文件。而後把pmvs2.exe/cmvs.exe/genOption.exe文件放到VisualSFM.exe的同目錄下。
通過 CMVS 對照片進行聚類,以減少稠密重建數據量,而後利用PMVS從3D模型的稀疏點雲開始,在局部光度一致性和全局可見性約束下,經過匹配、擴散、過濾 生成帶真實顏色的稠密點雲。(下圖爲用Meshlab查看效果圖)
至此,VisualSFM的工作告一段落,結果都已存盤。若因圖片匹配失敗或圖片較少導致某區域重建失敗或重建出的某區域細節不足,可以返回添加一些這個區域的照片,重新來過(本人較懶,未作補充,諒解)。但因特徵檢測和匹配的結果已存盤( 每張圖像對應的.sift 和 .mat文件),所以已經匹配好的圖像不必再次匹配,會更快完成。
第二步:運行Meshlab
1. 打開bundle.rd.out 文件
a. 按鈕1,打開由 VisualSFM生成的存儲在xx.nvm.cmvs文件夾下的 bundle.rd.out 文件。隨後會詢問是否選擇照片列表文件,選擇同文件夾下的 “list.txt”即可。這一步會把相機及對應的照片導入進來,對後續的紋理處理至關重要。
b. 按鈕2,打開顯示層目錄,檢測相機載入是否正確, Render –> Show Camera,因可視化相機的尺寸比網格尺寸大得多,所以需調整相機的縮放因子,scale factor可以從0.001開始調小,直到相機位置清晰可見。
2. 稠密點雲代替稀疏點雲
a. 按鈕3,隱藏可視的稀疏點雲;
b. File –> Import Mesh加載稠密點雲(xx/00/models/option-0000.ply);VisualSFM生成多個.ply文件時,需合併成一個mesh。在載入的任何一個.ply上右鍵選“Flatter Visible Layers”。
3. 清除雜點
按鈕4選中雜點區,按鈕5刪除之。大致清了桌前的一些雜點。
4. 網格化
Filter –> Point Set–> Surface Reconstruction: Poisson.
利用Poisson Surface Reconstruction算法由稠密點雲生成多邊形網格表面。
參數可調, Octree Depth:控制着網格的細節,此值越大細節越豐富但佔內存越大運行起來慢,一般設10,可慢慢調大。
Poisson表面重建算法會生成一個“不漏水”氣泡,把所有場景對象包裹在其中。即模型是封閉的。可以移除多餘的面Filters –> Selection –> Select faces with edges longer than,而後刪除。
保存(整個project和mesh)。
5. 修復流形邊緣
後續的紋理處理要求網格化的模型必須是流形(MANIFOLD)的,因此需刪除非流形邊(簡單講就是任何由多面共享的邊)。Filters –> Selection –> Select Non-Manifold edges,而後刪除之。
6. 參數化(Parameterization)
Filter –> Texture –> Parameterization from registered rasters。
根據相機投影關係創建UV映射。
保存 (整個project和mesh)。
7. 投影紋理
Filter –> Texture –> Project active rasters color to current mesh, filling the texture。
可設置任意分辨率(512的2的二次方倍:512 / 1024 / 2048 / 4096 / 8192…)的紋理圖。
6和7可以合爲一步: Filter –> Texturing –> Parameterization + texturing from registered rasters.
8. 完成、導出
當你調整滿意了之後,File –> Save mesh as… a .obj文件。即可便有了一個包含你選定分辨率紋理的obj文件。
收官啦。而後關乎應用,就是拼想象的時候了!
更多細節參見:We Did Stuff 。