多帧点云数据拼接合并_PCL点云处理实践(二):点云的处理和拼接
濾除背景
我們獲得的點云可能包含一部分背景的點云。要去除背景,只保留人體信息,最簡單的方式是使用直通濾波器濾除較遠點。這部分代碼如下:1
2
3
4
5
6pcl::PassThrough<:pointxyz>pass; //設置濾波器對象
pass.setInputCloud(cloud); //設置輸入點云
pass.setFilterFieldName("z"); //設置過濾時所需要點云類型的z字段
pass.setFilterLimits(0.0,1.0); //設置在過濾字段上的范圍
//pass.setFilterLimitsNegative (true); //設置保留范圍內的還是過濾掉范圍內的
pass.filter(*cloud_filtered); //執行濾波,保存過濾結果在cloud_filtered
濾除背景也可以通過Kinect SDK實現,這部分可以參考SDK的“游戲者ID”。
移除離群點
激光掃描通常會產生密度不均勻的點云數據集。另外,測量中的誤差會產生稀疏的離群點,使效果更糟。因此對每個點的鄰域進行一個統計分析,并修剪掉那些不符合一定標準的點。1
2
3
4
5pcl::StatisticalOutlierRemoval<:pointxyz> sor;// 創建濾波器對象
sor.setInputCloud(cloud); //設置呆濾波的點云
sor.setMeanK(50); //設置在進行統計時考慮查詢點鄰近點數
sor.setStddevMulThresh(1.0); //設置判斷是否為離群點的閾值
sor.filter(*cloud_filtered); //執行濾波處理保存內點到cloud_filtered
下采樣
為什么要進行下采樣?
Kinect直接得到的點云數據非常龐大,由于我們下一步要對其進行配準和拼接處理,如果不對點云進行適當精簡,運算時間可能非常長。因此,要等效一個Point較少的點云,取代原始點云進行配準操作。
PCL實現的VoxelGrid類通過輸入的點云數據創建一個三維體素柵格(可把體素柵格想象為微小的空間三維立方體的集合),然后在每個體素(即,三維立方體)內,用體素中所有點的重心來近似顯示體素中其他點,這樣該體素就內所有點就用一個重心點最終表示,對于所有體素處理后得到過濾后的點云。1
2
3
4pcl::VoxelGrid<:pointcloud2>sor; //創建濾波對象
sor.setInputCloud(cloud); //設置需要過濾的點云給濾波對象
sor.setLeafSize(0.01f,0.01f,0.01f); //設置濾波時創建的體素大小為1cm立方體
sor.filter(*cloud_filtered); //執行濾波處理,存儲輸出cloud_filtered
點云拼接
配準
什么是配準
配準是將一個點云找到與另一個點云相對應的部分,并得到兩個點云之間的轉換矩陣。
配準之后,我們就可以將一個點云轉換到另一個點云所在的坐標系內。在同一個坐標系內的點云可以進行拼接,形成一個更大的點云。
PCL內置了許多配準算法,例如迭代最近點對(ICP)算法,正態分布變換算法,隨機一致采樣(ransac)算法,等等。實際使用中,往往需要根據點云的特征選取合適的算法。這里使用了ransac算法。
隨機抽樣一致性算法(RANSAC)
概述
RANSAC是“RANdom SAmple Consensus(隨機抽樣一致)”的縮寫。它可以從一組包含“局外點”的觀測數據集中,通過迭代方式估計數學模型的參數。
RANSAC通過反復選擇數據中的一組隨機子集來達成目標。被選取的子集被假設為局內點,并進行驗證。
算法
RANSAC算法的輸入是一組觀測數據,一個可以解釋或者適應于觀測數據的參數化模型,一些可信的參數。
模型對應的是空間中一個點云數據到另外一個點云數據的旋轉以及平移。
第一步隨機選取點云中的一個點對,利用其不變特征(兩點距離,兩點法向量夾角)作為哈希表的索引值搜索另一個點云中的一個對應點對,然后計算得到旋轉及平移的參數值。
用得到的變換模型去測試其它點,如果某個點適用于估計的模型,認為它也是局內點。
用所有假設的局內點去重新估計模型,重新計算旋轉及平移的參數。
和上一個模型進行比較:是否有更多的局內點和更小的錯誤率。
然后迭代上述過程,直到找到最好的模型,或達到迭代次數。
優勢和缺點
RANSAC的優點是它能從包含大量局外點的數據集中估計出高精度的參數。
RANSAC的缺點是它計算參數的迭代次數沒有上限;如果設置迭代次數的上限,得到的結果可能不是最優的結果,甚至可能得到錯誤的結果。RANSAC只有一定的概率得到可信的模型,概率與迭代次數成正比。RANSAC的另一個缺點是它要求設置跟問題相關的閥值。
如何提高配準的精確度
對于兩個點云來說,提高精確度的方法是選取合適的算法、增加迭代次數、修改參數。
實際配準中,我們可能要連續配準多個點云。這樣,在兩個點云匹配中出現的誤差可能被放大。嘗試了以下幾種思路:第n個點云與第n+1個點云配準,得到轉換矩陣。將第n-1個轉換矩陣乘以這個轉換矩陣,得到第n個轉換矩陣。第n+1個點云乘以第n個轉換矩陣,得到它投影到第1個點云所在坐標系的新點云。
上一方法的改進策略:同時由第1個點云向后出發,第n個點云向前出發進行配準,最終重合。
第n個點云與第n+1個點云配準,得到轉換矩陣,并將第n+1個點云乘以轉換矩陣,將得到的新點云替換第n+1個點云。
第n個點云與第n+1個點云配準,得到轉換矩陣,并將第n+1個點云乘以轉換矩陣,將得到的新點云拼接上第n個點云,然后替換第n+1個點云。
最終選擇了第二種方法,它可以達到較好的效果。
配準部分的代碼,根據采取的算法不同有所變化,建議從官方文檔參看這部分代碼。
最終效果
實際使用中,很難做到短時間高精度地配準出點云,對于一些情況,可能要進行有針對性的優化。這是測試中配準效果較好的一個:
總結
以上是生活随笔為你收集整理的多帧点云数据拼接合并_PCL点云处理实践(二):点云的处理和拼接的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php 共享内存列队,php中对共享内存
- 下一篇: ubuntu 虚拟机 串口 socket