小白:師兄,上次你講了點(diǎn)云拼接后,我回去費(fèi)了不少時(shí)間研究,終于得到了和你給的參考結(jié)果差不多的點(diǎn)云,不過(guò),這個(gè)點(diǎn)云“可遠(yuǎn)觀而不可近看”,放大了看就只有一個(gè)個(gè)稀疏的點(diǎn)了。究竟它能干什么呢?
師兄:這個(gè)問(wèn)題嘛。。。基本就和SLAM的作用一樣,定位和建圖小白:定位好理解,可是師兄說(shuō)建圖,這么稀疏的地圖有什么用呢?師兄:地圖分很多種,稀疏的,稠密的,還有半稀疏的等,你輸出的這個(gè)稀疏的地圖放大了看就是一個(gè)個(gè)離散的空間點(diǎn),不過(guò)我們可以把它變成連續(xù)的稠密的網(wǎng)格,這個(gè)過(guò)程也叫點(diǎn)云的網(wǎng)格化小白:哇塞,聽(tīng)起來(lái)好高大上呢,具體怎么做呢?師兄:點(diǎn)云網(wǎng)格化需要對(duì)點(diǎn)云進(jìn)行一系列處理,今天我們先說(shuō)說(shuō)點(diǎn)云處理流程的第一步,叫做點(diǎn)云濾波
為什么要對(duì)點(diǎn)云濾波?
小白:濾波是什么鬼?
師兄:濾波最早來(lái)自在數(shù)字信號(hào)處理里的概念,你可以理解為是一個(gè)過(guò)濾器,是對(duì)點(diǎn)云的一種預(yù)處理方法
小白:哦哦,想起來(lái)中學(xué)學(xué)的濾紙,就是可以過(guò)濾掉雜質(zhì)那種師兄:哈哈,對(duì),這個(gè)很形象了,你看下面這個(gè)圖,左側(cè)就是原來(lái)的點(diǎn)云,右側(cè)是經(jīng)過(guò)濾波后濾掉的“雜質(zhì)”
小白:師兄,那是所有的點(diǎn)云一開(kāi)始都要濾波嗎?師兄:如果你的點(diǎn)云本來(lái)就非常好了,就不需要了。一般下面這幾種情況需要進(jìn)行點(diǎn)云濾波處理:(1) 點(diǎn)云數(shù)據(jù)密度不規(guī)則需要平滑(2) 因?yàn)檎趽醯葐?wèn)題造成離群點(diǎn)需要去除(3) 大量數(shù)據(jù)需要下采樣(4) 噪聲數(shù)據(jù)需要去除
小白:前三點(diǎn)還能勉強(qiáng)理解,這第四點(diǎn)中點(diǎn)云中噪聲數(shù)據(jù)從哪里來(lái)的呢?師兄:這個(gè)很多因素啦!一方面來(lái)自設(shè)備。比如我們用激光掃描儀、RGB-D相機(jī)等設(shè)備獲取點(diǎn)云數(shù)據(jù)時(shí),由于設(shè)備精度,電磁波的衍射特性等都會(huì)引入噪聲的。另一方面來(lái)自環(huán)境因素帶來(lái)的影響,比如被測(cè)物體表面性質(zhì)發(fā)生變化。還有一個(gè)重要的方面就是操作者經(jīng)驗(yàn)帶來(lái)的影響,比如在處理點(diǎn)云數(shù)據(jù)拼接配準(zhǔn)等操作過(guò)程中引入的一些噪聲等。
小白:嗯嗯,原來(lái)噪聲數(shù)據(jù)這么容易混進(jìn)來(lái)啊。那怎么去掉他們呢?或者說(shuō)怎么樣濾波呢?說(shuō)濾波好像顯得更專業(yè)一點(diǎn)哈師兄:點(diǎn)云中的噪聲點(diǎn)對(duì)后續(xù)操作的影響比較大。就像蓋房子一樣,地基有很多瑕疵,如果不加以處理最終可能會(huì)導(dǎo)致整個(gè)房子坍塌的。不過(guò)別擔(dān)心,PCL中有一個(gè)專門(mén)的點(diǎn)云濾波模塊,可以將噪聲點(diǎn)去除,還可以進(jìn)行點(diǎn)云壓縮等操作,非常靈活實(shí)用,例如:雙邊濾波,統(tǒng)計(jì)濾波,條件濾波,隨機(jī)采樣一致性濾波等。這樣才能夠更好的進(jìn)行配準(zhǔn),特征提取,曲面重建,可視化等后續(xù)應(yīng)用處理。小白:那太好啦,PCL都幫我們想到啦,我迫不及待的想要實(shí)踐一下啦。具體怎么操作呢?師兄:濾波模塊主要是調(diào)用一些封裝好的濾波函數(shù),然后根據(jù)需要設(shè)定一下參數(shù),還是很直觀的。
一般來(lái)說(shuō),濾波對(duì)應(yīng)的方案有如下幾種:(1)按照給定的規(guī)則限制過(guò)濾去除點(diǎn)(2) 通過(guò)常用濾波算法修改點(diǎn)的部分屬性(3)對(duì)數(shù)據(jù)進(jìn)行下采樣
小白:哦哦,這么多函數(shù)啊,哪里有這個(gè)濾波函數(shù)大全呢?方便我需要的時(shí)候去查查用哪個(gè)的那種?
師兄:有的,PCL中關(guān)于點(diǎn)云濾波的所有函數(shù)都在這里:http://docs.pointclouds.org/trunk/group__filters.html下面我們舉兩個(gè)例子介紹一下,簡(jiǎn)單的熟悉一下濾波的過(guò)程
點(diǎn)云下采樣
師兄:我先說(shuō)一下數(shù)據(jù)下采樣吧,這個(gè)最簡(jiǎn)單小白:師兄,能不能問(wèn)下為啥要下采樣?我有強(qiáng)迫癥,每做一件事情前都想知道原因。。。師兄:嗯,這個(gè)不算強(qiáng)迫癥啦,是個(gè)好習(xí)慣!了解原因了就知道什么時(shí)候用嘛!我舉個(gè)例子,比如我們上次點(diǎn)云融合,一張640x480 的Depth圖,假如每個(gè)地方都有深度值,可以轉(zhuǎn)化為30萬(wàn)個(gè)點(diǎn)組成的點(diǎn)云,如果有幾十張上百?gòu)垐D這樣暴力融合,那這個(gè)融合的點(diǎn)云會(huì)越來(lái)越大,儲(chǔ)存、操作都是個(gè)大問(wèn)題!
小白:是不是相當(dāng)于我有個(gè)大容量的樣本,我按一定的規(guī)則從里面抽取有代表性的樣本,可以代替原來(lái)的樣本,是這樣嗎?師兄:對(duì),理解的很到位。這個(gè)下采樣PCL中有專門(mén)的類,叫做
classpcl::ApproximateVoxelGrid
它比較適合對(duì)海量的點(diǎn)云在處理前進(jìn)行數(shù)據(jù)壓縮,就像我們上次講的點(diǎn)云融合后的數(shù)據(jù)那樣,而且可以在特征提取等處理中選擇合適的體素(voxel)大小等參數(shù),提高算法效率。該函數(shù)對(duì)輸入的點(diǎn)云數(shù)據(jù)創(chuàng)建一個(gè)三維體素柵格,每個(gè)體素內(nèi)用體素中所有點(diǎn)的重心來(lái)近似顯示體素中其他點(diǎn),這樣該體素內(nèi)所有點(diǎn)都用一個(gè)重心點(diǎn)最終表示。它的優(yōu)點(diǎn)是可以在下采樣的時(shí)候保存點(diǎn)云的形狀特征。看下面是它的結(jié)果,左邊是待處理的右邊是處理前,右邊是處理后
小白:看起來(lái)確實(shí)形狀保持的挺好,這個(gè)怎么編程實(shí)現(xiàn)?
師兄:其實(shí)關(guān)鍵就下面幾行代碼
pcl::VoxelGrid
每行代碼的意義都注釋好了,應(yīng)該不難理解小白:看起來(lái)好像也不麻煩師兄;嗯,上面只是經(jīng)常用的成員函數(shù),還有一些其他成員函數(shù),我這里只重點(diǎn)介紹兩個(gè)一個(gè)是
setLeafSize(floatlx,floatly,floatlz)
setLeafSize后面的三個(gè)參數(shù)表示體素柵格葉大小,分別表示體素在XYZ方向的尺寸,以米為單位,上面就是設(shè)置為長(zhǎng)寬高都為1cm另外一個(gè)是設(shè)置是否對(duì)所有的字段進(jìn)行下采樣,成員函數(shù)為
setDownsampleAllData(booldownsample)
小白:師兄,這個(gè)字段是啥意思?師兄:哦,不好意思,忘記解釋了。我們知道點(diǎn)云有不同的類型,比如有的是 PointXYZ,有的是PointXYZRGB,還有其他類型,也就是一個(gè)點(diǎn)包含多種不同信息,比如空間位置XYZ,顏色信息RGB,或者強(qiáng)度信息等,如果想要對(duì)所有信息(字段)下采樣則設(shè)置為true,只對(duì)XYZ下采樣的話設(shè)置為false
如何充分了解每個(gè)類的功能?
小白:嗯,了解啦,不過(guò)我有個(gè)問(wèn)題,我想要用這個(gè)下采樣類時(shí)怎么知道它有哪些函數(shù)可以用呢?師兄:這個(gè)好問(wèn)題,PCL官網(wǎng)上一般都有例程,但是例程包含的成員函數(shù)是很有限的,所以如果你想要了解這個(gè)濾波模板類的所有功能,或者說(shuō)內(nèi)聯(lián)成員函數(shù)的話,最好的辦法就是去官網(wǎng)查詢。我們還是以pcl::ApproximateVoxelGrid 模板類為例進(jìn)行說(shuō)明
第一步,登錄PCL API documentation http://docs.pointclouds.org/trunk/
第二步:在右上角搜索框內(nèi)輸入我們要查詢的模板類名稱,這里我們輸入ApproximateVoxelGrid,如下所示,會(huì)自動(dòng)跳出來(lái)匹配的結(jié)果
第三步:選擇你要找的類名,點(diǎn)擊進(jìn)入,就到了下面這個(gè)界面,列出了所有的成員變量和成員函數(shù),點(diǎn)擊每個(gè)成員函數(shù),會(huì)跳到對(duì)應(yīng)的解釋界面
你看除了我們前面提到的幾個(gè)成員函數(shù),其實(shí)還有好幾個(gè)我們沒(méi)用到的都在這里了,需要的話可以使用啦,就是這樣簡(jiǎn)單
小白:授人以魚(yú)不如授人以漁,謝謝師兄!以后我可以自己查函數(shù)啦
去除點(diǎn)云的離群點(diǎn)
師兄:剛才下采樣只是萬(wàn)里長(zhǎng)征第一步,下面說(shuō)一下去除離群點(diǎn)方法。小白:等下,師兄,什么是離群點(diǎn)啊?師兄:哦,忘了解釋這個(gè)術(shù)語(yǔ)了,抱歉,我簡(jiǎn)單說(shuō)一下,離群點(diǎn)對(duì)應(yīng)的英文是outliers,也叫外點(diǎn),就是明顯偏離“群眾”的點(diǎn),比如我們用激光掃描一面平坦的墻壁,正常情況下得到的應(yīng)該是差不多也位于同一個(gè)平面的點(diǎn)云,但是由于設(shè)備測(cè)量誤差等原因,會(huì)產(chǎn)生少量脫離群眾的空間點(diǎn),離本來(lái)的墻壁過(guò)遠(yuǎn),我們就叫這部分點(diǎn)為離群點(diǎn)。
小白:哈哈,離群點(diǎn)就是脫離群眾的壞點(diǎn),明白啦!不過(guò)這些點(diǎn)不是很少嗎?有必要趕盡殺絕嗎?師兄:“趕盡殺絕”,很形象的比喻!哈哈,還是很有必要的,因?yàn)殡x群點(diǎn)會(huì)使局部點(diǎn)云特征(如表面法線或曲率變化)的估計(jì)復(fù)雜化,從而導(dǎo)致錯(cuò)誤的值,從而可能導(dǎo)致點(diǎn)云配準(zhǔn)失敗。而且這些離群點(diǎn)還會(huì)隨著積累進(jìn)行傳導(dǎo),不早點(diǎn)消滅會(huì)有很大隱患的。
小白:原來(lái)危害這么大,那師兄趕快告訴我該怎樣消滅它們吧!師兄:好,我這里列舉兩個(gè)常用的去除離群點(diǎn)的類,第一個(gè)類叫做 StatisticalOutlierRemoval ,顧名思義,使用統(tǒng)計(jì)分析技術(shù),從一個(gè)點(diǎn)云數(shù)據(jù)中集中移除測(cè)量噪聲點(diǎn),也就是離群點(diǎn)啦!
小白:聽(tīng)起來(lái)很高大上啊,那具體是什么統(tǒng)計(jì)分析技術(shù)呢?師兄:主要是對(duì)每個(gè)點(diǎn)的鄰域進(jìn)行統(tǒng)計(jì)分析,剔除不符合一定標(biāo)準(zhǔn)的鄰域點(diǎn)。具體來(lái)說(shuō),對(duì)于每個(gè)點(diǎn),我們計(jì)算它到所有相鄰點(diǎn)的平均距離。假設(shè)得到的分布是高斯分布,我們可以計(jì)算出一個(gè)均值 μ 和一個(gè)標(biāo)準(zhǔn)差 σ,那么這個(gè)鄰域點(diǎn)集中所有點(diǎn)與其鄰域距離大于μ + std_mul * σ 區(qū)間之外的點(diǎn)都可以被視為離群點(diǎn),并可從點(diǎn)云數(shù)據(jù)中去除。std_mul 是標(biāo)準(zhǔn)差倍數(shù)的一個(gè)閾值,可以自己指定。
小白:嗯,聽(tīng)起來(lái)還是挺科學(xué)的,槍打出頭鳥(niǎo)嘛!師兄,這個(gè)原理我懂啦,重點(diǎn)是怎么編程呢?師兄:這里有個(gè)示例代碼
pcl::StatisticalOutlierRemoval
小白:和前面下采樣的形式很像哎師兄:嗯,PCL都幫你寫(xiě)好了,你只需要?jiǎng)?chuàng)建對(duì)象,設(shè)置參數(shù)就行啦。小白:師兄可以稍微解釋一下上面代碼嗎?師兄:好,這個(gè)應(yīng)該不難看懂。你看,我們先創(chuàng)建統(tǒng)計(jì)分析濾波器,然后設(shè)置濾波器輸入是 cloud,也就是我們待處理的點(diǎn)云,然后設(shè)置對(duì)每個(gè)點(diǎn)分析的臨近點(diǎn)的個(gè)數(shù)設(shè)置為50 ,并將標(biāo)準(zhǔn)差的倍數(shù)設(shè)置為1, 這意味著如果一個(gè)點(diǎn)的距離超出了平均距離加上一個(gè)標(biāo)準(zhǔn)差以上,則該點(diǎn)被標(biāo)記為離群點(diǎn),并將它移除。最后統(tǒng)計(jì)分析濾波后,輸出的結(jié)果就是cloud_filtered小白:師兄這么一解釋感覺(jué)容易理解多了,這個(gè)方法效果怎么樣?
師兄:效果還是挺不錯(cuò)的,你看下圖展示了稀疏離群值分析和移除的效果:原始數(shù)據(jù)集顯示在左邊,結(jié)果集顯示在右邊。圖中紅色表示濾波前的平均k近鄰距離,綠色表示濾波后的平均k近鄰距離,可以看到毛刺明顯少了很多。
小白:嗯嗯,效果明顯,看的見(jiàn)!師兄:另外,還有一個(gè)比較簡(jiǎn)單常用的方法就是根據(jù)空間點(diǎn)半徑范圍臨近點(diǎn)數(shù)量來(lái)濾波,對(duì)應(yīng)的類名是 RadiusOutlinerRemoval,這個(gè)很容易理解,它的濾波思想非常直接,就是在點(diǎn)云數(shù)據(jù)中,設(shè)定每個(gè)點(diǎn)一定半徑范圍內(nèi)周?chē)辽儆凶銐蚨嗟慕彛粷M足就會(huì)被刪除。小白:這個(gè)半徑范圍是怎么定的?師兄:因?yàn)榭臻g點(diǎn)的具體坐標(biāo)都是知道的,所以我們可以很方便的計(jì)算某個(gè)點(diǎn)和它周?chē)悬c(diǎn)的歐氏距離,這些都是以米為單位的,可以直接指定具體的數(shù)值,對(duì)于三維建模很實(shí)用。
下圖就是該類的篩選方法。比如你指定了一個(gè)半徑d,然后指定該半徑內(nèi)至少有1個(gè)鄰居,那么下圖中只有黃色的點(diǎn)將從點(diǎn)云中刪除。如果指定了半徑內(nèi)至少有2個(gè)鄰居,那么黃色和綠色的點(diǎn)都將從點(diǎn)云中刪除。
小白:確實(shí)很直觀,編程怎么實(shí)現(xiàn)呢?師兄:編程實(shí)現(xiàn)的簡(jiǎn)單例子在這里:
pcl::RadiusOutlierRemoval
小白:確實(shí)用法都差不多,我按照前面師兄講的方法充分了解每個(gè)類的功能,就會(huì)用啦!師兄:嗯,今天篇幅已經(jīng)比較長(zhǎng)了,雖然感覺(jué)才講了一點(diǎn),下次我們?cè)僦v網(wǎng)格化吧!小白:好,那下次再聊啦,謝謝師兄!
-
數(shù)字信號(hào)
+關(guān)注
關(guān)注
2文章
972瀏覽量
47585 -
SLAM
+關(guān)注
關(guān)注
23文章
425瀏覽量
31860
原文標(biāo)題:從零開(kāi)始一起學(xué)習(xí)SLAM | 給點(diǎn)云加個(gè)濾網(wǎng)
文章出處:【微信號(hào):IV_Technology,微信公眾號(hào):智車(chē)科技】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論