點云(Point Cloud)
接觸三維重建或者立體視覺相關問題的時候,點云是第一個需要掌握的概念。
簡單來講,點云就是多唯空間中的點的集合,一般而言,指的是三維空間中的點集。在PCL中,點云被表示成一種數據結構。我們用X-Y-Z三維來表示一個采樣曲面的幾何坐標。如下,當我們對其表面著色后,點云變為4唯的。
獲取點云的方式有很多:比如一些硬件傳感器(如立體相機,3D掃描儀,TOF相機),或者通過程序計算,比如SFM算法。
很高興的是PCL原生支持OpenNI從而能夠很好的直接處理深度相機( PrimeSensor 3D cameras, Microsoft Kinect和 Asus XTionPRO)的數據。另外說明一下,Kinect和華碩的這款本質上都是采用PrimeSense的結構光技術的深度相機。OpenNI現在也由Primesense維護,而Primesense已被蘋果收購。有時間對這些硬件和產業,包括眼鏡和深度相機也做一下歸納吧。
PCL(Point Cloud Library)簡介
點云庫Point Cloud Library (or PCL) 是一個大型的用于處理2D/3D圖像和點云的開源項目。它實現了立體視覺領域眾多的前沿算法,包括濾波,特征提取,表面重建,相機標定,模型擬合,分割,可視化等許多功能,如圖。
PCL項目遵循 3-clause BSD license 協議,能同時用于學術和商業用途。它也是跨平臺的,目前支持五大平臺(Linux,MacOS, Windows, 和 Android/iOS. )
目前,與立體視覺結合最緊密的研究方向當屬機器人了,PCL與機器人操作系統ROS集成良好,并已經有很好的實際應用。SLAM移動機器人導航,尤其是VisualSLAM領域的蓬勃發展,VR/AR的不斷發酵,三維重建等的發展會更加促進立體視覺的發展,PCL的重要性不言而喻。
PCL代碼風格良好,全部由C++編寫,其中的矩陣操作使用了線性代數函數庫Eigen。此外,PCL也支持并行化,如OpenMP和Intel Threading Building Blocks。在PCL的所有模塊中,數據的傳遞都是通過Boost的智能指針Share Pointer,如此可以減少系統中數據的多余復制。
再來說下PCL的各個模塊,它們可以獨立編譯,獨立運行。它的一般工作模式如下:
- 新建一個處理類(Project)(比如,filter,feature estimation,segmentation等)
- 使用
setInputCloud
將點云(Point Cloud)數據輸入到處理模塊中 - 設定一些必要的參數
- 調用
compute
或者其他的函數如(filter,segment等)得到輸出
主要模塊包括:
-
libpcl_filter:
功能包括將采樣(downsampling),例外點去除,索引提取,投影等 -
libpcl_features:
實現了許多3D特征,比如表面法向量和曲率,邊緣點估計,不變矩(moment invariants),主曲率,PFH和FPFH(Fast point feature histogram)描述子,旋轉圖像(spin image),積分圖像(integral image),NARF描述符,RIFT,RSD,VFH,基于強度數據的SIFT算法等。
后面我覺得也會有一些采用深度學習方法訓練特征的算法加入到PCL中。 -
libpcl_io:
I/O操作的函數,如讀寫點云數據PCD(point cloud data)的函數 -
libpcl_segmentation:
實現了聚類提取,或者為某些參數模型通過采樣一致的方法提供模型擬合等 -
libpcl_surface:
實現了表面重建的一些算法,如meshing,圖包算法(convex hull)和移動最小二乘(moving least squares)等 -
libpcl_registration:
ICP匹配算法等 -
libpcl_keypoints:
預處理的一些算法,對關鍵點預處理方便后續提取特征描述符 -
libpcl_range_image:
深度圖(range image)的建立函數等
為了保證操作的正確性,上述每個庫中的方法和類都提供了單元和回歸測試,如果添加的新功能或者某個修改沒有通過測試,該作者會收到通知。
PCL的設計哲學
Perception Processing Graphs
這個道理的潛在認為對點云處理的各個模塊可以認為是獨立編譯的一部分,通過調整參數可以分別應對某一類問題。
由于點云數據通常比較大,為了避免不必要的拷貝和關鍵程序的序列化,PCL創建了nodelets,一種可以動態加載的插件模式。
可視化
PCL基于VTK實現了自己的可視化庫,從而方便用戶快速查看自己的模型,不管這種模型是通過參數公式設定還是從點云而來。
可視化庫也提供了渲染(rendering)以及處理PCD的方法等。使用可視化庫的一般流程如下:
using namespace pcl visualization;
PCLVisualizer p (“Test”);
PointCloudColorHandlerRandom handler (cloud);
p.addPointCloud (cloud, handler, ”cloud random”);
p.spin ();
p.removePointCloud (”cloud random”);
PointCloudGeometryHandlerSurfaceNormal handler2 (cloud);
p.addPointCloud (cloud, handler2, ”cloud random”);
p.spin ();
貢獻代碼的好處
使用開源庫的用戶會遇到兩個問題:
- 有新的需求,而開源庫還沒有更新
- 功能有Bug,但是沒有fix
這個時候如果你完成了上述工作,那么別人也許會從中受益。換個角度,如果每個人碰到這種情況都采取這種處理方式呢?
總而言之,開源項目,就是大家合作一起做一件事,我為人人,人人為我。
再引用Linus法則“given enough eyeballs, all bugs are shallow”,貢獻你的代碼給大家閱讀,你的代碼會面臨挑戰,會促使你不斷提高自己的代碼質量。還有,程序員的榮譽和成就感,這些也是參與其中才能體會到的。
當然,每個人的情況不一樣,就不一一列舉啦。
Next 將會介紹如何著手貢獻一個具體的功能源碼以及介紹PCL的源碼風格