快速點特征直方圖(FPFH)描述子
已知點雲P中有n個點,那么它的點特征直方圖(PFH)的理論計算復雜度是,其中k是點雲P中每個點p計算特征向量時考慮的鄰域數量。對於實時應用或接近實時應用中,密集點雲的點特征直方圖(PFH)的計算,是一個主要的性能瓶頸。此處為PFH計算方式的簡化形式,稱為快速點特征直方圖FPFH(Fast Point Feature Histograms)
為了簡化直方圖的特征計算,我們執行以下過程:
第一步,對於每一個查詢點 ,計算這個點和它的鄰域點之間的一個元組 (參考上一節PFH的介紹),第一步結果我們稱之為簡化的點特征直方圖SPFH(Simple Point Feature Histograms);
第二步,重新確定每個點的k鄰域,使用鄰近的SPFH值來計算的最終直方圖(稱為FPFH)
權重 在一些給定的度量空間中,表示查詢點 和其鄰近點 之間的距離,因此可用來評定一對點( , ),但是如果需要的話,也可以把用 另一種度量來表示。如圖1所示可以幫助理解這個權重方式的重要性,它表示的是以點 為中心的k鄰域影響范圍。
以點 為中心的k鄰域影響范圍圖
因此,對於一個已知查詢點 ,這個算法首先只利用 和它鄰域點之間對應對(上圖中以紅色線來說明),來估計它的SPFH值,很明顯這樣比PFH的標准計算少了鄰域點之間的互聯。點雲數據集中的所有點都要執行這一計算獲取SPFH,接下來使用它的鄰近點 的SPFH值和 點的SPFH值重新權重計算,從而得到 點的最終FPFH值。FPFH計算添加的計算連接對,在上圖中以黑色線表示。如上圖所示,一些重要對點(與 直接相連的點)被重復計數兩次(圖中以粗線來表示),而其他間接相連的用細黑線表示。
PFH和FPFH的區別
PFH和FPFH計算方式之間的主要區別總結如下:
1.FPFH沒有對全互連 點的所有鄰近點的計算參數進行統計,從圖中可以看到,因此可能漏掉了一些重要的點對,而這些漏掉的對點可能對捕獲查詢點周圍的幾何特征有貢獻。
2.PFH特征模型是對查詢點周圍的一個精確的鄰域半徑內,而FPFH還包括半徑r范圍以外的額外點對(不過在2r內);
3.因為重新權重計算的方式,所以FPFH結合SPFH值,重新捕獲鄰近重要點對的幾何信息;
4.由於大大地降低了FPFH的整體復雜性,因此FPFH有可能使用在實時應用中;
5.通過分解三元組,簡化了合成的直方圖。也就是簡單生成d分離特征直方圖,對每個特征維度來單獨繪制,並把它們連接在一起
估計FPFH特征
快速點特征直方圖FPFH在點雲庫中的實現可作為pcl_features庫的一部分。默認的FPFH實現使用11個統計子區間(例如:四個特征值中的每個都將它的參數區間分割為11個),特征直方圖被分別計算然后合並得出了浮點值的一個33元素的特征向量,這些保存在一個pcl::FPFHSignature33點類型中。以下代碼段將對輸入數據集中的所有點估計一組FPFH特征值。
#include #include //fpfh特征估計類頭文件聲明 ...//其他相關操作 pcl::PointCloud<pcl::PointXYZ>::Ptrcloud(new pcl::PointCloud<pcl::PointXYZ>); pcl::PointCloud<pcl::Normal>::Ptrnormals(new pcl::PointCloud<pcl::Normal>()); ...//打開點雲文件估計法線等 //創建FPFH估計對象fpfh,並把輸入數據集cloud和法線normals傳遞給它。 pcl::FPFHEstimation<pcl::PointXYZ,pcl::Normal,pcl::FPFHSignature33> fpfh; fpfh.setInputCloud(cloud); fpfh.setInputNormals(normals); //如果點雲是類型為PointNormal,則執行fpfh.setInputNormals (cloud); //創建一個空的kd樹對象tree,並把它傳遞給FPFH估計對象。 //基於已知的輸入數據集,建立kdtree pcl::search::KdTree<PointXYZ>::Ptrtree(new pcl::search::KdTree<PointXYZ>); fpfh.setSearchMethod(tree); //輸出數據集 pcl::PointCloud<pcl::FPFHSignature33>::Ptrfpfhs(new pcl::PointCloud<pcl::FPFHSignature33>()); //使用所有半徑在5厘米范圍內的鄰元素 //注意:此處使用的半徑必須要大於估計表面法線時使用的半徑!!! fpfh.setRadiusSearch(0.05); //計算獲取特征向量 fpfh.compute(*fpfhs); // fpfhs->points.size ()應該和input cloud->points.size ()有相同的大小,即每個點有一個特征向量
FPFHEstimation類的實際計算內部只執行以下操作:
對點雲P中的每個點p
第一步:
1.得到:math:`p`的鄰域元素
2. 計算每一對:math:`p, p_k`的三個角度參數值(其中:math:`p_k`是:math:`p`的鄰元素)
3.把所有結果統計輸出到一個SPFH直方圖
第二步:
1.得到:math:`p`的最近鄰元素
2.使用:math:`p`的每一個SPFH和一個權重計算式,來計算最終:math:`p`的FPFH
估計一點雲的VFH特征
視點特征直方圖(或VFH)是源於FPFH描述子(見Fast Point Feature Histograms (PFH) 描述子)。由於它的獲取速度和識別力,我們決定利用FPFH強大的識別力,但是為了使構造的特征保持縮放不變性的性質同時,還要區分不同的位姿,計算時需要考慮加入視點變量。我們做了以下兩種計算來構造特征,以應用於目標識別問題和位姿估計:1.擴展FPFH,使其利用整個點雲對象來進行計算估計(如2圖所示),在計算FPFH時以物體中心點與物體表面其他所有點之間的點對作為計算單元。2.添加視點方向與每個點估計法線之間額外的統計信息,為了達到這個目的,我們的關鍵想法是在FPFH計算中將視點方向變量直接融入到相對法線角計算當中。
通過統計視點方向與每個法線之間角度的直方圖來計算視點相關的特征分量。注意:並不是每條法線的視角,因為法線的視角在尺度變換下具有可變性,我們指的是平移視點到查詢點后的視點方向和每條法線間的角度。第二組特征分量就是前面PFH中講述的三個角度,如PFH小節所述,只是現在測量的是在中心點的視點方向和每條表面法線之間的角度
因此新組合的特征被稱為視點特征直方圖(VFH)。下圖表體現的就是新特征的想法,包含了以下兩部分:
1.一個視點方向相關的分量
2.一個包含擴展FPFH的描述表面形狀的分量
估計VFH特征值
視點特征直方圖在PCL中的實現屬於pcl_features模塊庫的一部分。對擴展的FPFH分量來說,默認的VFH的實現使用45個子區間進行統計,而對於視點分量要使用128個子區間進行統計,這樣VFH就由一共308個浮點數組成陣列。在PCL中利用pcl::VFHSignature308的點類型來存儲表示。PFH/FPFH描述子和VFH之間的主要區別是:對於一個已知的點雲數據集,只一個單一的VFH描述子,而合成的PFH/FPFH特征的數目和點雲中的點數目相同。以下代碼段將對輸入數據集中的所有點估計一組VFH特征值。
#include <pcl/point_types.h> #include <pcl/features/vfh.h> //VFH特征估計類頭文件 ...//其他相關操作 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>); pcl::PointCloud<pcl::Normal>::Ptr normals (new pcl::PointCloud<pcl::Normal> ()); ...//打開點雲文件估計法線等 //創建VFH估計對象vfh,並把輸入數據集cloud和法線normal傳遞給它 pcl::VFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::VFHSignature308> vfh; vfh.setInputCloud (cloud); vfh.setInputNormals (normals); //如果點雲是PointNormal類型,則執行vfh.setInputNormals (cloud); //創建一個空的kd樹對象,並把它傳遞給FPFH估計對象。 //基於已知的輸入數據集,建立kdtree pcl::KdTreeFLANN<pcl::PointXYZ>::Ptr tree (new pcl::KdTreeFLANN<pcl::PointXYZ> ()); vfh.setSearchMethod (tree); //輸出數據集 pcl::PointCloud<pcl::VFHSignature308>::Ptr vfhs (new pcl::PointCloud<pcl::VFHSignature308> ()); //計算特征值 vfh.compute (*vfhs); // vfhs->points.size ()的大小應該是1,即vfh描述子是針對全局的特征描述
微信公眾號號可掃描二維碼一起共同學習交流