pcl里面的3D特征
我這里不介紹pcl里面的類的命名規范,及點的類型。為什么呢?pcl里面類的命名規范,比較繁瑣,而且主要是針對要對pcl這個庫要開源的人士,而pcl里面的點的類型太多,足夠滿足你的要求。所以我們要走一條具有中國特色的pcl主義道路。
今天來介紹一下pcl里面的3D特征。
點是用來給一個給定區域來用笛卡爾坐標系x,y,z來進行描繪的一種方式。假定坐標系統的坐標原點沒有變,可能會有兩個點比如p1和p2,成為t1和t2,但是它們的坐標是沒變的。
比較這些點云是不穩定的,因為即使他們有相同的距離,但是它們可能采自不同的表面,因此他們可能會代表不同的信息,當把它們和表面上臨近的點結合在一起的時候。這是因為很難確?,F實世界里面的t1和t2沒有變化。有一些獲取點云的裝置可能會獲取一些額外的數據,比如亮度(intensity),比如表面光滑度(翻譯不一定對,surface remission value),和顏色等等,但是以上的這些往往還是不能解決問題。
程序往往需要更好的特征或者是矩來區別幾何表面。所以把3D點看成笛卡爾坐標系里面的一個單一的實體這個概念消失了,我們引入了一個局部坐標系。文化是豐富多彩,森羅萬象的,我們可以對同樣的概念取很多的命名組合,比如形狀描述,幾何特征,而在pcl里面是用點的特征來描述。
通過包含周邊的點,采樣表面的幾何特征可以被我們給推理或者捕獲,這將解決我們蛋疼的比較問題。理想情況下,同一個或者相似表面上的點的特征是很相似的。那么怎么來找到一個比較好的,描述點的特征呢?當這個特征在下面這3個因素的影響下,還能或得同樣的表面特點的時候就是好的特征。
1.剛體轉換。這包括了3D旋轉與3D轉換,好的特征應該不會被此影響,特征向量F(feature)不會改變。
2.不同的采樣密度??傮w來說,一個局部的表面區域,不管以高密度還是低密度的采樣,應該具有相同的特征向量。
3.噪聲。這個不需要過多的解釋。
總體來說,pcl里面使用相似的方法來查詢指定點的最近鄰,如使用kd-trees。下面是我們感興趣的2個查詢時需要的類型;
1.k。即查詢時的最近鄰的點的個數。
2.r。即搜索半徑。
專業術語:
| Foo | a class named?Foo //英文里面很多隨便取的類叫foo或bar類似張三,李四 |
| FooPtr | a boost shared pointer to a class?Foo,//boost共享指針 e.g.,?boost::shared_ptr<Foo> |
| FooConstPtr | a const boost shared pointer to a classFoo,//boost共享常量指針 e.g.,?const boost::shared_ptr<const Foo> |
怎么進行輸入?
pcl里面基本上所有的類都繼承自pcl::PCLBase這個類,所有pcl::Feature有兩個方式來獲取輸入數據。
1.輸入為整個點云數據集,setInputCloud(PointCloudConstPtr&)??強制的
這將計算每一個輸入點的特征。
2.輸入為一個點云數據集的子集。setInputCloud(PointCloudPtr&)和setIndices(IndicesConstPtr&)?后面那個是可選的。
這將計算給定下標的輸入點的特征。默認情況下下標是不會給的,也就意味著每個點的特征都會被計算。
除此之外,我們還可以通過別的調用,如setSearchSurface(PointCloudConstPtr &)來搜索表面上的點。
1.setIndices()=false,setSearchSurface()=false
這是pcl里面用的最多的,不用任何的特征來排除點云,即包含所有的點。
因為我們不希望根據是否有下標或者是否有表面來確定不同的點云的拷貝,pcl內部創造了一系列的向量,來指向整個數據集。
最左邊的那幅圖,它先找到p1的最近鄰,再找p2的最近鄰,直到?把P這個點云里面的點窮盡。
2.setIndices()=true,setSearchSurface()=false
這只會計算在給定的下標向量里面的下標所對應點的特征,比如p1是屬于下標向量里面的,而p2不屬于,則只會計算p1附近的點的特征。
3.setIndices()=false,setSearchSurface()=true
只會計算潛在表面的最近鄰的點的特征,而不是整個點云。比如P和Q是兩個點云,然后把P作為要被搜索的表面(潛在的表面),則Q的每個元素(q1,q2)會在P中找到最近的幾個點。
4.setIndices()=true,setSearchSurface=true.這可能是最稀少的情況了,因為這既要滿足下標,又要滿足表面搜索。最后一幅圖里面,先通過下標把q2給排除,然后再搜索q1在P里面的最近鄰。
我們使用setSearchSurface()最多的例子,是當我們有一個高密度的輸入數據集的時候,但是我們不想去計算里面所有點的特征,在這個例子里面我們通過setSearchSurface()來解決這個問題,而不是通過downsample(降低采樣,往往通過pcl::VoxelGrid<T>?filter)或者keypoints(關鍵采樣)。我們把downsampled/keypoints作為setInputCloud()的輸入,即是setSearchSurface()的原始數據集。
法線估計的一個例子
一旦決定了某個要查詢點的周圍的局部特征代表,就可以捕獲查詢點的潛在表面的幾何特征。在描述一個表面的幾何特征的第一步是得到它在某個坐標下的方向,因此要估計它的法線。下面的代碼段將預測輸入數據集的一系列表面法線。
下面的代碼段將通過一個輸入數據集預測一系列表面法線,用另一個輸入數據集評估最近鄰。像前面提到的,這是一個降低表面采樣得到的數據集,作為輸入。
#include <pcl/point_types.h> #include <pcl/features/normal_3d.h>{pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_downsampled (new pcl::PointCloud<pcl::PointXYZ>);... read, pass in or create a point cloud ...... create a downsampled version of it ...// Create the normal estimation class, and pass the input dataset to itpcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne;ne.setInputCloud (cloud_downsampled);// Pass the original data (before downsampling) as the search surfacene.setSearchSurface (cloud);// Create an empty kdtree representation, and pass it to the normal estimation object.// Its content will be filled inside the object, based on the given surface dataset.pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ> ());ne.setSearchMethod (tree);// Output datasetspcl::PointCloud<pcl::Normal>::Ptr cloud_normals (new pcl::PointCloud<pcl::Normal>);// Use all neighbors in a sphere of radius 3cmne.setRadiusSearch (0.03);// Compute the featuresne.compute (*cloud_normals);// cloud_normals->points.size () should have the same size as the input cloud_downsampled->points.size () }還有通過下標來降低采樣的,下面這個例子
總結
以上是生活随笔為你收集整理的pcl里面的3D特征的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python数模笔记-NetworkX(
- 下一篇: python基础课程7(看代码看注释)-