霍佳欣 楊家志
(桂林理工大學信息科學與工程學院 廣西 桂林 541006)
近年來很多學者在三維點云的數據處理領域做出了很多的貢獻。三維點云數據在很多方面有廣泛的應用,如3D重建、逆向工程、自動駕駛、醫療等[1-4]。激光雷達掃描是目前獲取點云數據的主要方式。但由于一些人為或環境因素,以及激光雷達掃描裝置本身的缺陷,通常會導致獲取的三維數據帶有一定的噪聲,而這些噪聲數據會給后續建模和測量中的相關處理帶來嚴重的問題[5-7]。因此,三維點云濾波是建模前的關鍵步驟。
噪聲大多數表現為高頻率信息,常用的大多數去噪方法基本上都是過濾掉高頻率的信息,保存低頻率的信息。但是,三維點云模型中所具有的幾何特征也是屬于高頻率信息,因此過濾除去高頻率的信息有可能會錯誤地刪除點云模型的尖銳幾何特征,從而丟失特征相關的信息。而通過視覺觀察物體時,對物體上所具有的特征比較敏感,所以三維點云模型數據的處理不但要去除噪聲,并且也要保持三維點云數據模型特征。在分析噪聲產生原因的基礎上,可以將噪聲進行分類,分為大尺度噪聲也就是距離點云模型較遠的噪聲、小尺度噪聲也就是距離模型較近的小尺度噪聲兩類,并分別進行三維點云數據處理。
點云數據處理常用的基于數學形態學濾波的算法[8]、斜率濾波[9]、TIN漸進加密算法[10]等雖然在去除點云數據模型主體上的小振幅噪聲方面有很好的效果,但對于一些離群的點大多數不能通過自適應的方法去除,只能手工去除,這給點云數據去除噪聲帶來很多的困難。基于移動最小二乘法(MLS)的[11-12]和基于局部最優投影(LOP)的方法在去噪效果上有很好的表現,但是通常噪聲點云模型的過渡平滑,從而丟失幾何特征。雖然雙邊濾波算法[13]可以很好地保持邊緣特征,但是該算法在時間上消耗較大。針對以上算法處理點云時存在的問題,本文提出一種新的去噪算法,可以把噪聲進行合理的分類,分為大尺度的噪聲類和小尺度的噪聲類。大尺度噪聲具有的特點是小而密集的點云,具有高頻、大幅值等。存在于點云主體內部或者邊界的散亂點,可以稱之為小尺度噪聲點,分別使用統計學濾波和引導濾波進行去噪。
現實世界中的三維點云數據模型是包含很多特征的包括尖銳特征,如邊界和角點等,很多三維點云去噪的算法對于點云模型的邊界信息以及角等尖銳特征往往會被忽略,這樣就會對點云的數據處理產生很大的影響。保持點云的尖銳特征的目的就是為了能夠重新構造出精確的三維點云特征模型。濾波的目的是有效地平滑三維點云噪聲和消除模型中的噪聲,并保留物體表面原有的細節特征。算法的主要思想是先通過統計學濾波算法去除點云的大尺度噪聲,保留尖銳特征,之后再通過引導濾波算法進行小尺度噪聲的去除。本文算法去噪流程如圖1所示。

圖1 點云去噪流程
1.1.1統計學濾波核心代碼
pcl:: StatisticalOutlierRemoval
//創建去噪對象
sor.setInputCloud(cloud); //設置需要進行去噪的點云對象
sor.setMeanK(m); //設置 m 為在進行統計時考慮查詢點
//鄰近點數
sor.setStddevMulThresh(1.0);
//設置距離閾值,
sor.filter(*cloud_filtered);
//執行去噪計算并保存點到
//cloud_filtered
1.1.2引導濾波核心代碼
pcl:: KdTreeFLANN
//創建kd樹對象
kdtree.setInputCloud(cloud);
//輸入帶濾波的點云數據
kdtree.setEpsilon(epsilon);
//設置濾波半徑
Eigen:: Vector3d mean;
mean=neighbors_as_matrix.rowwise().mean();
//計算矩陣每行的均值
neighbors_as_matrix.transposeInPlace();
//臨近點矩陣轉置
Eigen:: MatrixXd centered=neighbors_as_
matrix.rowwise()-neighbors_as_matrix.colwise().mean();
//計算矩陣的中心
Eigen:: MatrixXd cov=(centered.adjoint() * centered) / double(neighbors_as_matrix.rows()-1);
//計算矩陣的協方差
Eigen:: MatrixXd e=(cov + epsilon * Eigen:: MatrixXd:: Identity(3,3));
e=e.inverse();
Eigen:: MatrixXd A=cov*e;
Eigen:: MatrixXd b=mean-A*mean;
//通過公式計算線性系數
searchPointEigenType=A*searchPointEigenType+b;
//計算濾波后的點云數據
激光掃描通常生成的點云數據集具有不同的密度,此外,激光掃描得到的點云數據會有稀疏的異常值產生,這是因為測量誤差,從而進一步破壞點云的表達準確性,使得局部點云特征的估計復雜化,從而導致錯誤的估計結果,進而導致點云的高層應用表現不佳。明顯離群點的特征是在空間中分布稀疏,基于離群點的特征可以認為:三維點云數據集中每個點是包括一定信息量的,越密集地分布在某個區域,則可能表示的信息量越大。噪聲信息對于三維點云數據模型是屬于無用信息,且包含的信息量相對來說較小,所以可以忽略不計??紤]到離群點的特征,則可以定義一個密度,某處點云密度和定義密度作比較,如果小于定義的密度,即可以稱為點云無效也就是大尺度噪聲。根據大尺度噪聲的特點采用統計學濾波算法對此類噪聲進行去噪處理。統計學濾波可以通過構建K-D樹數據結構來構建KNN(k-nearest neighbor)[14],進而有效對離散點云數據進行劃分和管理,加快了計算速度。對于大尺度點云統計濾波算法流程如下所示。
Step1讀入存儲點云數據的PCD文件,讀取三維點云數據為P(p1,p2,…,pn)。
Step2對點云的數據點建立K-D樹的數據結構,通過K近鄰算法進行K近鄰搜索。
Step3對于點云的每個點pi,定義參數K為近鄰點的個數,根據K的值通過K近鄰算法建立鄰域,并計算點云中每個點與其最近的K個點的距離的平均值。
Step4在Step3的基礎上。計算點云集中所有點的K近鄰點平均距離μ和其標準差σ。
Step5式(1)中的α指的是準差倍數閾值,為確定標準范圍D,設置參數μ表示為三維點云數據模型中所有點的K近鄰點距離的平均值,設置參數σ表示為三維點云數據模型中所有點的K近鄰點距離的標準差。一個點的距離的平均值的差值和準差倍數閾值α作比較,如果低于α,則這一點就會被劃分為非噪聲點進而保留,否則認為該點是噪聲點進而把這個點刪除。
D=μ+α×σ
(1)
Step6遍歷點云數據集中的所有點,刪除大尺度噪聲的點云數據,保存沒有刪除的點云數據。
導引圖像濾波常用于圖像,是由He等[21]提出的一種時間效率高的保持特征的平滑算子。算法的基本思想是將輸出圖像作為窗口中制導圖像的線性變換。受引導圖像濾波的啟發,Han等[15]提出了引導點云濾波。由于考慮到三維點云數據與圖像不同,圖像包含強度信息,而三維點云數據不包含強度信息,直接將引導圖像濾波技術的方法用到三維點云濾波不容易實現。所以從三維點云的位置信息考慮,將引導圖像濾波技術擴展到點云濾波技術中形成一種通用的濾波器,為引導點云濾波。由于統計學濾波后的點云數據還有一部分小尺度噪聲需要去除,引導濾波不僅能去除小尺度噪聲,而且能保持點云邊緣。通過點云數據建立K-D樹結構對點Pi的臨近點搜索可以采用K近鄰搜索(KNN)或者半徑搜索。

(2)
式中:N(Pi)為點pi的臨近點。
Step2假設點云的局部線性模型為:
(3)

Step3通過對式(4)中點在KNN鄰域的極小值進行求解,因需要對平滑效果控制進而設置參數ε為平滑參數:
(4)
Step4對函數J(ai,bi)取極小值時,對ai和bi的偏導為零。解得:
(5)
(6)
Step5由Step4中的ai、bi,可以得到pi臨近點的濾波點云。
(7)
遍歷所有點云,得到濾波后的點云數據并保存,平滑參數取值通常是ε<1。
該方法的主要思想是利用導引點云的鄰域,將濾波后的輸出點推導為導引點云對應點的線性模型。
整體去噪算法偽代碼如算法1所示。
算法1整體去噪算法
輸入:P(p1,p2,…,pn)。
輸出:P(p1,p2,…,pn)。
//輸入需要去噪的點云數據
Create KNN tree
//通過KNN來查詢近鄰點
For each piont i=1 to N
//對數據集中每個點遍歷
Build all point K-D tree
//創建K-D樹
Build all point KNN
End for
Statistic filter
For each point i=1 to N
Caculate point KNN average distance
//計算每個點臨近點的平均距離
Caculate point KNN standard deviation
//計算每個點的方差
End for
Caculate all point KNN average distance μ
//計算所有點的臨近點的平均距離
Caculate all point KNN standard deviation σ
//計算所有點臨近點的方差
Determine the point is a noise point according to formula(1)
//通過公式(1)判斷點是否為噪聲點
Guided filter
Denoise the point according to section 1.2
According formula(2),(3),(4),(5),(6),(7)
OutputP(p1,p2,…,pn)
End
實驗的主要數據來自斯坦福大學點云模型庫[18]。選用兔子模型,對點云數據添加隨機噪聲。計算機CPU為Intel(R)Core(TM)i5-3317UCPU@1.70 GHz,8 GB內存; 操作系統為 Windows 10 64位; 編程環境為Visual Studio 2017+Point Cloud Library(PCL) 1.8.0。
帶噪聲的點云數據,通過統計學濾波算法去噪,此算法去除離群噪聲需要選擇合適的參數,圖2是不同參數下的去噪結果對比,α表示標準差倍數閾值,點云數據的不同臨近點個數通過設置參數K表示,取不同值消除點的個數。先確定參數α的值,因為如果α的值過小會導致部分離群點去除,如果α值過大又會使數據模型原本的數據去除。可以看出當α=1、K=20時較α=2、K=20和α=3、K=20去噪效果好,所以α=1是合適的參數。接下來確定參數K的值,α=1、K=20較α=1、K=30,α=1、K=40,α=1、K=50的去噪效果好,所以在統計學濾波去除大尺度噪聲參數時,合適的參數是α=1、K=20。在統計學濾波的基礎上選擇合適的引導濾波參數,通過實驗可以得出在進行引導濾波時,選擇半徑r=0.01、ε=0.1的參數值去噪效果表現最好,因為如果平滑參數過大會導致數據模型過度平滑,失去模型原有的幾何特征。

圖2 不同參數去噪對比
表1為帶噪聲的點云數據通過統計學濾波選擇不同的參數得出的結果,由噪點數的多少從而判斷合適的α與K的值,通過觀察當α=1、K=20時去除噪聲點數更多。綜上所述,α=1、K=20是統計學濾波最適合參數取值。

表1 不同參數去噪點的個數
兔子的點云模型數據點個數為35 947,原始點云模型如圖3(a)所示,可以看出模型周圍是沒有噪聲點的,在原始點云模型上加上3 000個隨機噪聲點,加噪聲之后點云數據點的個數為38 947,如圖3(b)所示。采用統計學方法之后可以明顯看出點云的離群點基本上被去除,還存在部分小尺度噪聲在兔子模型內部,如圖3(c)所示;通過體素化網格濾波,兔子模型周圍還存在較多大尺度噪聲,如圖3(d)所示;半徑濾波算法雖然去除了點云模型的大部分大尺度噪聲,但是兔子模型周圍還有小部分大尺度噪聲,如圖3(e)所示。本文算法兔子周圍大尺度噪聲基本上被去除,小尺度噪聲也被平滑,如圖3(e)所示,可以看出本文算法去噪效果較好,兔子模型的噪聲點基本上被去除。
為了驗證本文算法的去噪效果,在Bunny模型上與體素網格濾波算法[16]、半徑濾波算法[17]進行了比較,其中體素網格算法和半徑濾波算法在點云庫(PCL)版本1.8.0中提供,通過C++實現。
通過表2算法的運行結果可知,本文算法噪聲濾除率要比體素網格濾波算法提升45.5百分點,比半徑濾波算法提升了6.7百分點,表明本文算法具有較好的去噪效果。

表2 算法性能比較
本文將統計學濾波算法和引導濾波方法相結合,應用于三維點云數據的去噪。對于兩類噪聲的去除,實驗結果表明統計學濾波去除大尺度噪聲有很好的表現,引導點云濾波在去除小尺度噪聲上面也有很好的表現。所以本文算法在去除大尺度噪聲的同時也去除了小尺度噪聲,本文算法可以有效提高噪聲濾除率,并能較好地保留有效原始點云數據,可以應用于激光雷達裝置采集的帶噪聲的點云數據通過噪聲分類進行去噪。