PCL中點特征描述子PFH、FPFH和VFH簡述和示例


文章目錄

  • 前言
  • 一、點特征直方圖
    • 1.1 PFH
      • 1.1.1 法線估計
      • 1.1.2 特征計算
    • 1.2 FPFH
    • 1.3 VFH
  • 二、示例
    • 2.1 PFH計算
    • 2.2 FPFH
    • 2.3 VFH


前言

點特征直方圖是PCL中非常重要的特征描述子,在點云匹配、分割、重建等任務中起到關鍵作用,可以對剛體變換、點云密度和噪聲均有較強的抑制作用。而不同的描述子擁有不同優劣勢,需要根據具體情況選擇使用。


一、點特征直方圖

點特征直方圖融合了點云的局部和全局信息,具有旋轉平移不變性,以及對采樣密度和噪聲點的穩健性。

1.1 PFH

PFH(point feature histogram)通過估計查詢點和近鄰點之間的法線差異,計算得到一個多維直方圖來對點的K近鄰進行幾何描述,計算復雜度為O(nk^2)。
PFH的計算需要先估計法線,然后計算鄰域范圍內所有兩點之間的關系:

1.1.1 法線估計

PCL采用近似估計的方法來計算法線特征,通過NormalEstimation類完成。
計算過程:
通過估計近鄰區域的擬合面,再去計算查詢點的法線。
擬合過程通過最小二乘法完成,然后通過PCA方法計算得到法向量(構建協方差矩陣,奇異值分解計算矩陣最小特征值所對應的特征向量做為法向量),最后通過計算相鄰點法線內積的方法來進行法線定向。
實現過程可以參考:
為什么用PCA做點云法線估計?
源代碼:

inline boolcomputePointNormal (const pcl::PointCloud<PointInT> &cloud, const std::vector<int> &indices,float &nx, float &ny, float &nz, float &curvature){//計算協方差矩陣if (indices.size () < 3 ||computeMeanAndCovarianceMatrix (cloud, indices, covariance_matrix_, xyz_centroid_) == 0){nx = ny = nz = curvature = std::numeric_limits<float>::quiet_NaN ();return false;}// Get the plane normal and surface curvaturesolvePlaneParameters (covariance_matrix_, nx, ny, nz, curvature);return true;}

計算法線和曲率,其中nx,ny,nz為法線的xyz分量。

inline void
solvePlaneParameters (const Eigen::Matrix3f &covariance_matrix,float &nx, float &ny, float &nz, float &curvature)
{// Avoid getting hung on Eigen's optimizers
//  for (int i = 0; i < 9; ++i)
//    if (!std::isfinite (covariance_matrix.coeff (i)))
//    {
//      //PCL_WARN ("[pcl::solvePlaneParameteres] Covariance matrix has NaN/Inf values!\n");
//      nx = ny = nz = curvature = std::numeric_limits<float>::quiet_NaN ();
//      return;
//    }// Extract the smallest eigenvalue and its eigenvectorEIGEN_ALIGN16 Eigen::Vector3f::Scalar eigen_value;EIGEN_ALIGN16 Eigen::Vector3f eigen_vector;pcl::eigen33 (covariance_matrix, eigen_value, eigen_vector);nx = eigen_vector [0];ny = eigen_vector [1];nz = eigen_vector [2];// Compute the curvature surface changefloat eig_sum = covariance_matrix.coeff (0) + covariance_matrix.coeff (4) + covariance_matrix.coeff (8);if (eig_sum != 0)curvature = std::abs (eigen_value / eig_sum);elsecurvature = 0;
}

確定法線方向,vp_x,vp_y,vp_z為視點的坐標:

 template <typename PointT> inline voidflipNormalTowardsViewpoint (const PointT &point, float vp_x, float vp_y, float vp_z,float &nx, float &ny, float &nz){// See if we need to flip any plane normalsvp_x -= point.x;vp_y -= point.y;vp_z -= point.z;// Dot product between the (viewpoint - point) and the plane normalfloat cos_theta = (vp_x * nx + vp_y * ny + vp_z * nz);// Flip the plane normalif (cos_theta < 0){nx *= -1;ny *= -1;nz *= -1;}}

1.1.2 特征計算

在這里插入圖片描述
1:計算兩點法線的差異角度。
2:計算查詢點法線方向與兩點連線方向的角度。
3:計算鄰域點法線上一點到UW平面的垂線交點與鄰域點的直線,再計算直線與U的角度值。
4:計算兩點間的距離。
在這里插入圖片描述
按以上公式,每兩個查詢點可以計算出4個特征值。PCL中忽略d特征,只保留3個角度特征。
特征的統計方式按照劃分子區間,并統計每個子區間的點數目,同時將角度歸一化到相同的區間。PCL將每個角度特征劃分5個子區間進行統計,最終得到125個浮點元素的特征向量,可以保存在PFHSignature125類型中。
特征計算:

  PCL_EXPORTS bool computePairFeatures (const Eigen::Vector4f &p1, const Eigen::Vector4f &n1, const Eigen::Vector4f &p2, const Eigen::Vector4f &n2, float &f1, float &f2, float &f3, float &f4);

直方圖計算:

template <typename PointInT, typename PointNT, typename PointOutT> void
pcl::PFHEstimation<PointInT, PointNT, PointOutT>::computePointPFHSignature (const pcl::PointCloud<PointInT> &cloud, const pcl::PointCloud<PointNT> &normals,const std::vector<int> &indices, int nr_split, Eigen::VectorXf &pfh_histogram)

1.2 FPFH

FPFH(Fast Point Feature Histograms)意為快速點特征直方圖,該算法對特征的計算進行了簡化,并運用特征加權的方式得到最終的FPFH特征。該算法減少了時間復雜度,增加了實時性。
具體的計算方法:
1:計算查詢點p鄰域范圍內的所有點對特征(只與查詢點相連的點對),得到PFH中三個角度特征,命名為SPFH特征。
2:計算鄰域內其他點的SPFH特征。
3:將鄰域內其他所有的SPFH特征加權得到最終的FPFH特征,權重w是用鄰域內點的距離來進行度量的。PCL中將三個特征值中的每個按照11個特征子空間進行統計,組合得到一個33個浮點元素的特征向量來表示FPFH特征。
在這里插入圖片描述

1.3 VFH

為了使計算得到的特征保持尺度不變性和區分不同的位姿,故引入視點變量,計算得到視點特征直方圖VFH特征。
其計算方法為:
1:擴展FPFH,使其利用整個點云來進行計算估計,以點云的中心點c與其他點之間的點對作為計算單元。
2: 添加視點方向與每個點估計法線間的統計信息,其做法是在特征計算時將視點變量直接融入法線角度計算中來。
在這里插入圖片描述
具體可參考:
PCL 估計一點云的VFH特征
計算出的特征由三部分構成:
1:三個角度特征,每個分為45個子區間進行統計。
2:基于質心的點云形狀描述子,分為45個子區間進行統計。
3:視角方向與點法線方向的角度差異,分為128個子區間進行統計。

二、示例

2.1 PFH計算

    //讀取點云pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_ptr(new pcl::PointCloud<pcl::PointXYZ>);pcl::PCDReader reader;reader.read("plant.pcd", *cloud_ptr);//計算法線pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne;ne.setInputCloud(cloud_ptr);pcl::search::KdTree<pcl::PointXYZ>::Ptr tree1(new pcl::search::KdTree<pcl::PointXYZ>());ne.setSearchMethod(tree1);pcl::PointCloud<pcl::Normal>::Ptr cloud_normals_ptr(new pcl::PointCloud<pcl::Normal>);pcl::PointCloud<pcl::Normal>& cloud_normals = *cloud_normals_ptr;ne.setRadiusSearch(0.01);ne.compute(cloud_normals);//計算pfh特征pcl::PFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::PFHSignature125> pfh;pfh.setInputCloud(cloud_ptr);pfh.setInputNormals(cloud_normals_ptr);pcl::search::KdTree<pcl::PointXYZ>::Ptr tree2(new pcl::search::KdTree<pcl::PointXYZ>());pfh.setSearchMethod(tree2);//輸出pcl::PointCloud<pcl::PFHSignature125>::Ptr pfh_ptr(new pcl::PointCloud<pcl::PFHSignature125>());pfh.setRadiusSearch(0.03);pfh.compute(*pfh_ptr);//顯示pcl::visualization::PCLPlotter plotter;plotter.addFeatureHistogram(*pfh_ptr, 200); plotter.plot();

在這里插入圖片描述

2.2 FPFH

	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);pcl::PCDReader reader;reader.read("plant.pcd", *cloud);//法向量計算pcl::NormalEstimationOMP<pcl::PointXYZ, pcl::Normal> n;//OMP加速n.setInputCloud(cloud);pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());n.setSearchMethod(tree);n.setNumberOfThreads(4);n.setKSearch(30);pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);n.compute(*normals);//計算特征pcl::FPFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::FPFHSignature33> fpfh;fpfh.setInputCloud(cloud);fpfh.setInputNormals(normals);pcl::search::KdTree<pcl::PointXYZ>::Ptr tree2(new pcl::search::KdTree<pcl::PointXYZ>());fpfh.setSearchMethod(tree2);pcl::PointCloud<pcl::FPFHSignature33>::Ptr fpfh_fe(new pcl::PointCloud<pcl::FPFHSignature33>());//注意:此處使用的半徑必須要大于估計表面法線時使用的半徑fpfh.setRadiusSearch(0.03);fpfh.compute(*fpfh_fe);cout << "phf feature size : " << fpfh_fe->points.size() << endl;pcl::visualization::PCLPlotter plotter;plotter.addFeatureHistogram(*fpfh_fe, 200);plotter.plot();

在這里插入圖片描述


2.3 VFH

	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);pcl::PCDReader reader;reader.read("plant.pcd", *cloud);pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne;pcl::search::KdTree<pcl::PointXYZ>::Ptr tree1(new pcl::search::KdTree<pcl::PointXYZ>());ne.setInputCloud(cloud);ne.setSearchMethod(tree1);ne.setRadiusSearch(0.01);pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);ne.compute(*normals);pcl::VFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::VFHSignature308> vfh;vfh.setInputCloud(cloud);vfh.setInputNormals(normals);pcl::search::KdTree<pcl::PointXYZ>::Ptr tree2(new pcl::search::KdTree<pcl::PointXYZ>());vfh.setSearchMethod(tree2);pcl::PointCloud<pcl::VFHSignature308>::Ptr vfh_ptr(new pcl::PointCloud<pcl::VFHSignature308>());vfh.compute(*vfh_ptr);pcl::visualization::PCLPlotter plotter;plotter.addFeatureHistogram(*vfh_ptr, 200);plotter.plot();

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/256052.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/256052.shtml
英文地址,請注明出處:http://en.pswp.cn/news/256052.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

BZOJ 1005: [HNOI2008]明明的煩惱

BZOJ 1005: [HNOI2008]明明的煩惱 Description 自從明明學了樹的結構,就對奇怪的樹產生了興趣......給出標號為1到N的點,以及某些點最終的度數,允許在 任意兩點間連線,可產生多少棵度數滿足要求的樹? Input 第一行為N(0 < N < 1000), 接下來N行,第i1行給出第i個節點的度…

Apache Directory 指令

<Directory> 指令 語法&#xff1a;<Directory directory-path> ... </Directory> <Directory>和</Directory>用于封裝一組指令&#xff0c;使之僅對某個目錄及其子目錄生效。任何可以在"directory"作用域中使用的指令都可以使用。Dir…

來一個炫酷的導航條

本文分享一個帶動畫效果的中英文切換導航條。 鼠標放上去試一下&#xff1a; INDEX 首頁 BBS 社區 HOME 我 1.用CSS3實現 效果看上去復雜&#xff0c;其實我們先來做出一個樣式&#xff0c;就很簡單了。如下&#xff1a; 代碼&#xff1a; <nav><ul class"list…

基于C++的opencv中Mat矩陣運算方法總結

文章目錄前言一、Mat運算種類1.1 代數運算1.2 類型轉換前言 Mat類是目前opencv最為常用的圖像數據格式&#xff0c;其優點在于無需手動開辟內存空間和實時釋放&#xff0c;針對此類的各種運算方法有很多&#xff0c;本文按照各種運算方法的種類進行簡單的總結和示例。 一、Mat…

【pyqt5】——信號與槽

一、簡單Demo 簡單使用信號和槽&#xff08;之前常用的使用方式&#xff09;&#xff1a; class DemoWin(QMainWindow):def __init__(self):super().__init__()self.initUI()def initUI(self):self.resize(400, 250)self.btn QPushButton("發送信號", self)# 發送…

JSON - 簡介

JSON - 簡介 JSON實例 <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>菜鳥教程(runoob.com)</title> </head> <body> <h2>JavaScript 創建 JSON 對象</h2> <p> 網站名稱: <spa…

mysql慢日志管理

一、日志切割 原理&#xff1a; 1、cp一個慢日志備份 2、清空原理的慢日志 3、寫成腳本&#xff0c;每天一切&#xff0c;這樣就ok啦 二、查找日志中的慢日志 1、做了日志切割&#xff08;慢日志文件就小了&#xff09; 2、查找某個時間的慢日志 日志時間格式&#xff1a; # Ti…

【深度學習】mask_rcnn訓練自己的數據集以及模型使用(實踐結合GitHub項目)

根據requirements - 開源項目默認的.txt進行庫安裝 環境&#xff1a;WIN10 Anoconda Pycharm python3.6.2 mask_rcnn基本流程1、訓練 1)labelme進行目標物體標記&#xff0c;生成json文件&#xff0c;含點坐標、以及各個物體的標簽label; json文件的格式&#xff1a;&…

EXCEL小技巧:如何統計非空單元格

http://club.excelhome.net/thread-1187271-1-1.html 下面教大家如果用函數統計非空單元格的數量 首先我們來介紹幾個統計函數&#xff1a; 1.COUNT(value1,value2,...) 統計包含數字的單元格個數 2.COUNTA(value1,value2,...) 統計非空單元格的個數 3.COUNTBLANK(range&…

easyui 頁簽

昨天開始搭后臺框架&#xff0c;到晚上的時候遇到了一個現在覺得挺可笑但是當時一直很糾結很糾結的問題&#xff0c;這個問題剛剛解決出來&#xff0c;把它拿出來說說&#xff0c;讓自己長點兒記性&#xff0c;希望大家不要犯我這個錯誤啊 在backstage.jsp頁面中我寫了一個方法…

未在本地計算機上注冊“Microsoft.Jet.OLEDB.4.0”提供程序。

報錯信息&#xff1a; 解決方案&#xff1a; 1、“設置應用程序池默認屬性”/“常規”/”啟用32位應用程序”&#xff0c;設置為 true。 如下圖所示&#xff1a;&#xff08;已測試&#xff0c;好使&#xff09; 方法二&#xff1a;生成->配置管理器->平臺->點擊Any C…

UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figur

“UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure”在利用mask_rcnn進行物體檢測的時候出現的問題&#xff0c;主要是因為matplotlib的使用格式不對 可以檢查者兩個地方&#xff1a; 1、visualize.py中 import mat…

008. 限制上傳文件的大小

第一種方法: 利用web.config的配置文件項, 進行設置; 前端aspx示例: <% Page Language"C#" AutoEventWireup"true" CodeFile"sendOutEmail.aspx.cs" Inherits"sendOutEmail" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHT…

查詢實例及其代碼

一、 設有一數據庫&#xff0c;包括四個表&#xff1a;學生表&#xff08;Student&#xff09;、課程表&#xff08;Course&#xff09;、成績表&#xff08;Score&#xff09;以及教師信息表&#xff08;Teacher&#xff09;。四個表的結構分別如表1-1的表&#xf…

pyinstaller打包執行exe出現“ModuleNotFoundError: No module named ‘scipy.spatial.transform._rotation_group”

這個是因為打包后的第三方庫中缺少了pyd文件 具體的解決方法&#xff1a; 去環境下找到相應的py文件&#xff0c;根據https://blog.csdn.net/qq_41007606/article/details/109565069文章寫的方法&#xff0c;將py編譯成pyd文件&#xff0c;然后將pyd文件復制到dist相應的第三…

浙江中醫藥大學第十一屆程序設計競賽題解

官方題解&#xff1a;http://www.jnxxhzz.com/Article/article/9.html 2019: 特產 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 548 Solved: 154[Submit][Status][Web Board]Description Input Output 輸出一個整數表示dd帶回來的特產重量 Sample Input 2 3 6 1 3Sample …

vijos p1002——過河(noip2005提高組T2)

描述 在河上有一座獨木橋&#xff0c;一只青蛙想沿著獨木橋從河的一側跳到另一側。在橋上有一些石子&#xff0c;青蛙很討厭踩在這些石子上。由于橋的長度和青蛙一次跳過的距離都是正整數&#xff0c;我們可以把獨木橋上青蛙可能到達的點看成數軸上的一串整點&#xff1a;0&…

JNI學習

1. 目前調用關系已經搞清楚&#xff0c;需要編譯一個so或者dll的動態庫給java調用。 2. env有很多方法現在還不清楚&#xff0c; 獲得屬性句柄。 JNI方法描述符&#xff0c;主要就是在括號里放置參數&#xff0c;在括號后面放置返回類型&#xff0c;如下&#xff1a;&#xff0…

【項目實戰】——USB雙路繼電器電腦控制燈的開關(Python)

環境&#xff1a;window10、Python3.7.9 依賴庫&#xff1a;pyserial 硬件&#xff1a;220V燈帶、220V吊燈、USB雙路繼電器、電筆 1、安裝Python第三方庫pyserial 2、清楚插座的零火線&#xff08;用電筆去測試&#xff0c;燈亮為火線&#xff09; 3、清楚燈的零火線&#…

字符串去掉空格

2019獨角獸企業重金招聘Python工程師標準>>> String s1s.trim().replaceAll("\\s*", ""); 轉載于:https://my.oschina.net/u/2842177/blog/1587850