一、引言
點(diǎn)云濾波,是對(duì)點(diǎn)云數(shù)據(jù)處理的常用功能。
相機(jī)采集的圖像,受限于拍攝條件、光照、物件表面反光及補(bǔ)光角度等原因,會(huì)導(dǎo)致攝像頭成像質(zhì)量下降,進(jìn)而導(dǎo)致在進(jìn)行點(diǎn)云重建時(shí)會(huì)包含一些噪點(diǎn)。包括飛點(diǎn)、彌散點(diǎn)、甚至是憑空出現(xiàn)的點(diǎn),因此若需要得到高質(zhì)量點(diǎn)云,可以選擇對(duì)點(diǎn)云數(shù)據(jù)進(jìn)行一次濾波,提升數(shù)據(jù)質(zhì)量。
當(dāng)然提高質(zhì)量手段有很多,從環(huán)境上調(diào)優(yōu)光照、調(diào)整拍攝角度,從拍攝上進(jìn)行HDR、參數(shù)調(diào)整,或從算法上調(diào)整等,本文將先基于點(diǎn)云濾波展開討論。
二、濾波原理
本文講述濾波方法為基于鄰域的濾波。顧名思義就是會(huì)計(jì)算每個(gè)點(diǎn)與周圍鄰域內(nèi)有效點(diǎn)的數(shù)量,根據(jù)相關(guān)程度來決定當(dāng)前點(diǎn)是否需要被過濾。

將點(diǎn)云2D平面化后,如上圖:
(假設(shè)紅色為鄰域點(diǎn),半徑d為鄰域距離閾值)
每個(gè)單獨(dú)點(diǎn)云的鄰域相關(guān)情況,一般來說分為3種:
-
黃色點(diǎn):鄰域內(nèi)沒有相關(guān)的點(diǎn),作為噪點(diǎn)直接排除
-
藍(lán)色點(diǎn):鄰域內(nèi)有大量相關(guān)的點(diǎn),作為有效點(diǎn)保留
-
綠色點(diǎn):鄰域內(nèi)有相關(guān)的點(diǎn),但是數(shù)量不足,也作為噪點(diǎn)排除
根據(jù)鄰域?yàn)V波原理,可以解決大部分噪點(diǎn),效果如下:

濾波前

濾波后
三、濾波實(shí)現(xiàn)
為了實(shí)現(xiàn)濾波,首先需要準(zhǔn)備點(diǎn)云間距離閾值,即原理圖中的半徑d。一般來說可以使用點(diǎn)云點(diǎn)間平均距離*6。此參數(shù)越大時(shí),濾波效果越差。參數(shù)越小時(shí)濾波效果越好。但是過小時(shí)可能會(huì)過濾掉有效點(diǎn)。
其次需要準(zhǔn)備鄰域內(nèi)相關(guān)數(shù)量閾值,即鄰域內(nèi)至少要有幾個(gè)點(diǎn)云才保留當(dāng)前點(diǎn)。本算法實(shí)現(xiàn)為搜索鄰域內(nèi)一共44個(gè)點(diǎn),有6個(gè)以上即判定為保留。此參數(shù)越大時(shí)濾波效果越好,參數(shù)越小時(shí)濾波效果越差。
通過兩個(gè)參數(shù)組合和調(diào)優(yōu),已經(jīng)可以勝任絕大部分場(chǎng)景下的點(diǎn)云濾波需求。
大致流程如下:
-
遍歷點(diǎn)云數(shù)據(jù)中每個(gè)點(diǎn)
-
根據(jù)距離閾值,檢查每個(gè)點(diǎn)鄰域內(nèi)相關(guān)點(diǎn)數(shù)量
-
根據(jù)相關(guān)數(shù)量閾值,確定點(diǎn)云數(shù)據(jù)是否保留
-
根據(jù)保留結(jié)果,將點(diǎn)云數(shù)據(jù)拷貝至新數(shù)據(jù)緩沖區(qū)
實(shí)現(xiàn)代碼如下:
漢振3D開發(fā)SDK中,可以直接調(diào)用點(diǎn)云濾波接口,使用方法如下:
參數(shù)解釋如下:
-
buffer:存儲(chǔ)點(diǎn)云基本數(shù)據(jù),需要按照3通道float方式存儲(chǔ)xyz數(shù)據(jù)
-
targetData:濾波后結(jié)果數(shù)據(jù),按照3通道float方式存儲(chǔ)xyz數(shù)據(jù)
-
1920:點(diǎn)云列數(shù)
-
1200:點(diǎn)云行數(shù)
-
0.5:質(zhì)心平均距離,也可以理解為點(diǎn)云點(diǎn)間平均距離
-
30:云間距離閾值
四、代碼加速
有了思路,實(shí)現(xiàn)了效果還不夠,代碼需要跑得快才能真的派上用處。對(duì)于點(diǎn)云濾波算法,可以有以下幾種加速思路:
01 多線程并行
即代碼中coreUtilsConcurrent部分。本算法中將點(diǎn)云按照行進(jìn)行拆分,分發(fā)給4個(gè)線程單獨(dú)處理。在4線程下可以提速2到3倍。這里要注意的一點(diǎn)是在現(xiàn)在基于CPU的運(yùn)算中,線程并不是越多越好,需要根據(jù)算法實(shí)際調(diào)整。對(duì)于本算法,4線程左右為宜,即使CPU物理上有8線程甚至16線程。主要原因是本算法較為簡單,內(nèi)存瓶頸比CPU運(yùn)算瓶頸更容易出現(xiàn)。線程多反而容易造成資源爭奪,降低緩存命中率,進(jìn)而導(dǎo)致性能下降。
02 鄰域相關(guān)度計(jì)算剪枝
即代碼循環(huán)體內(nèi)最大代碼量部分。算法中鄰域搜索邏輯是會(huì)先從點(diǎn)云當(dāng)前行開始,依次搜索-1行,+1行,-2行,+2行,-3行,+3行。結(jié)合物理世界中實(shí)際點(diǎn)云噪點(diǎn)分布情況,如果在當(dāng)前行和-1行都沒有搜索到符合條件的鄰域有效點(diǎn),那么在+1,-2行這些也大概率搜索不到鄰域有效點(diǎn),因此當(dāng)前點(diǎn)基本就是無效點(diǎn),就可以直接刪除。按照此邏輯類推,分別設(shè)置1、3、5個(gè)鄰域有效點(diǎn)的退出條件。通過此項(xiàng)剪枝后,可以提速2到4倍。
03 內(nèi)存訪問順序優(yōu)化
因?yàn)镃PU有緩存秒鐘問題,所以我們希望開發(fā)的程序盡可能提高緩存命中率,以提高運(yùn)行速度。對(duì)點(diǎn)云數(shù)據(jù)的訪問,在內(nèi)存上盡量從左到右訪問,從上到下訪問。
04 代碼減少判斷條件
部分可以通過內(nèi)聯(lián)展開,代碼結(jié)構(gòu)完成的判斷,可以直接通過寫代碼方式實(shí)現(xiàn),而不是通過for,函數(shù)調(diào)用方式使用。
05 減少對(duì)象拷貝
盡量通過全局變量保存熱點(diǎn)變量。例如點(diǎn)云數(shù)據(jù)指針,高寬等參數(shù),會(huì)被頻繁用到,可以保存到全局變量中讓后續(xù)流程可以直接訪問,而不是保存到中間變量反復(fù)拷貝,或者通過指針反復(fù)解指針使用。
進(jìn)行了如上幾點(diǎn)優(yōu)化后,230W點(diǎn)云濾波,可以控制在5到15ms以內(nèi)。
更多機(jī)器視覺產(chǎn)品信息與應(yīng)用說明,機(jī)器視覺算法,應(yīng)用技巧,解決方案以及相關(guān)領(lǐng)域的技術(shù)分享,歡迎繼續(xù)關(guān)注“漢振智能”....