PCL中GreedyProjection三角化算法簡介與示例


文章目錄

  • 前言
  • 一、PCL點云三角化
    • 1.1 Delaunay三角剖分
    • 1.2 貪婪三角化
  • 二、程序示例
  • 總結


前言

Delaunay三角剖分最初應用于2維領域,而與Greedy三角化算法的結合,使之成為目前在三維重建領域最為基礎的算法原理之一,很多學者針對其原理進行改進用以三維點云模型的構建。


一、PCL點云三角化

1.1 Delaunay三角剖分

定義:假設點集中的一條邊e(兩個端點為a,b),e若滿足下列條件,則稱之為Delaunay邊:存在一個圓經過a,b兩點,圓內(圓上最多三點共圓)不含點集中任何其他的點。而Delaunay三角化就是指三角網格均是由Delaunay邊組成,并滿足最小角最大原則(在點集可能形成的三角剖分中,Delaunay三角剖分所形成的三角形的最小角最大)。

針對以上定義,目前已提出了很多經典的剖分算法,如Lawson算法、Bowyer-Watson算法。以上算法都很有意思,通過點插法實現,具體原理可以查看以下鏈接。
技術分享:Delaunay三角剖分算法介紹
在這里插入圖片描述

1.2 貪婪三角化

PCL中采用將三維點云投影到二維平面的方法來實現三角剖分, 具體采用貪婪三角化算法。
其過程為:
1:計算點云中點的法線,再將點云通過法線投影到二維坐標平面。
2:使用基于Delaunay三角剖分的空間區域增長算法完成平面點集的三角化。
3:根據投影點云的連接關系確定原始三維點云間的拓撲關系,最終得到曲面模型。

PCL中的NormalEstimation和GreedyProjectionTriangulation類實現該計算過程。
源代碼:

FFN和SFN是指兩個不同方向的邊緣鄰域集,在connectPoint方法里完成計算。

/** \brief Index of the current query point **/
int R_;std::vector<int> ffn_;
std::vector<int> sfn_;
// Locating FFN and SFN to adapt distance thresholddouble sqr_source_dist = (coords_[R_] - coords_[source_[R_]]).squaredNorm ();double sqr_ffn_dist = (coords_[R_] - coords_[ffn_[R_]]).squaredNorm ();double sqr_sfn_dist = (coords_[R_] - coords_[sfn_[R_]]).squaredNorm ();double max_sqr_fn_dist = (std::max)(sqr_ffn_dist, sqr_sfn_dist);double sqr_dist_threshold = (std::min)(sqr_max_edge, sqr_mu * sqrDists[1]); //sqr_mu * sqr_avg_conn_dist);if (max_sqr_fn_dist > sqrDists[nnn_-1]){if (0 == increase_nnn4fn)PCL_WARN("Not enough neighbors are considered: ffn or sfn out of range! Consider increasing nnn_... Setting R=%d to be BOUNDARY!\n", R_);increase_nnn4fn++;state_[R_] = BOUNDARY;continue;}double max_sqr_fns_dist = (std::max)(sqr_source_dist, max_sqr_fn_dist);if (max_sqr_fns_dist > sqrDists[nnn_-1]){if (0 == increase_nnn4s)PCL_WARN("Not enough neighbors are considered: source of R=%d is out of range! Consider increasing nnn_...\n", R_);increase_nnn4s++;}

計算法線:

// Get the normal estimate at the current point 
const Eigen::Vector3f nc = (*input_)[(*indices_)[R_]].getNormalVector3fMap ();

三角化:

// Triangulatingif (angles_[2].visible == false){if ( !( (angles_[0].index == ffn_[R_] && angles_[1].index == sfn_[R_]) || (angles_[0].index == sfn_[R_] && angles_[1].index == ffn_[R_]) ) ){state_[R_] = BOUNDARY;}else{if ((source_[R_] == angles_[0].index) || (source_[R_] == angles_[1].index))state_[R_] = BOUNDARY;else{if (sqr_max_edge < (coords_[ffn_[R_]] - coords_[sfn_[R_]]).squaredNorm ()){state_[R_] = BOUNDARY;}else{tmp_ = coords_[source_[R_]] - proj_qp_;uvn_s[0] = tmp_.dot(u_);uvn_s[1] = tmp_.dot(v_);double angleS = std::atan2(uvn_s[1], uvn_s[0]);double dif = angles_[1].angle - angles_[0].angle;if ((angles_[0].angle < angleS) && (angleS < angles_[1].angle)){if (dif < 2*M_PI - maximum_angle_)state_[R_] = BOUNDARY;elsecloseTriangle (polygons);}else{if (dif >= maximum_angle_)state_[R_] = BOUNDARY;elsecloseTriangle (polygons);}}}}continue;}

源碼中大量代碼關注于三角形的連接問題。
最后調用MeshConstruction類的reconstruct方法進行表面重建。

template <typename PointInT> void
MeshConstruction<PointInT>::reconstruct (std::vector<pcl::Vertices> &polygons)
{if (!initCompute ()){polygons.clear ();return;}// Check if a space search locator was givenif (check_tree_){if (!tree_){if (input_->isOrganized ())tree_.reset (new pcl::search::OrganizedNeighbor<PointInT> ());elsetree_.reset (new pcl::search::KdTree<PointInT> (false));}// Send the surface dataset to the spatial locatortree_->setInputCloud (input_, indices_);}// Set up the output dataset//polygons.clear ();//polygons.reserve (2 * indices_->size ()); /// NOTE: usually the number of triangles is around twice the number of vertices// Perform the actual surface reconstructionperformReconstruction (polygons);deinitCompute ();
}

二、程序示例

//----------------------------------法線計算-----------------------------------pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> n;pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);pcl::search::KdTree<pcl::PointXYZ>::Ptr tree1(new pcl::search::KdTree<pcl::PointXYZ>);tree->setInputCloud(cloud);n.setInputCloud(cloud);n.setSearchMethod(tree1);n.setKSearch(20);n.compute(*normals);pcl::PointCloud<pcl::PointNormal>::Ptr cloud_with_normals(new pcl::PointCloud<pcl::PointNormal>);pcl::concatenateFields(*cloud, *normals, *cloud_with_normals);//連接點云和法線pcl::search::KdTree<pcl::PointNormal>::Ptr tree2(new pcl::search::KdTree<pcl::PointNormal>);tree2->setInputCloud(cloud_with_normals);pcl::GreedyProjectionTriangulation<pcl::PointNormal> gp;pcl::PolygonMesh triangles;gp.setSearchRadius(0.025);//設置搜索半徑,即連接點的最大距離gp.setMu(2.5); //加權因子,對于每個樣本點,其映射所選球的半徑由mu與離樣本點最近點的距離乘積決定,用以解決點云密度不均勻的問題,mu一般取值2.5-3gp.setMaximumNearestNeighbors(600); //最大領域點個數gp.setMaximumSurfaceAngle(M_PI / 4);//臨近點的法線和樣本點法線的最大偏離角度gp.setMinimumAngle(M_PI / 18); //三角形最小角gp.setMaximumAngle(2 * M_PI / 3);//三角形最大角gp.setNormalConsistency(false); //保證法線朝向一致gp.setInputCloud(cloud_with_normals);gp.setSearchMethod(tree2);   gp.reconstruct(triangles);

在這里插入圖片描述

總結

徹底理解三角化的源代碼比較困難,缺少相關學習資料,歡迎共同研究,提出意見。

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

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

相關文章

[設計模式]中介者模式之Events消息傳遞實現

這篇文章比較短,修改自 寫給大家看的設計模式之中介者中的例子中介者模式的定義和目的自不必說, 參考上文即可. 本文針對實現方式做一個補充. 中介者模式增加了一個第三方對象(中介者)來控制兩個對象(同事)間的交互. 有助于對彼此通信的解耦, 畢竟他們并不需要關心對方的實現細…

【pyqt5】 讀取numpy arrray 顯示圖片

目錄 1、GUI界面&#xff08;QT designer設計&#xff09; 2、邏輯函數&#xff08;回調等&#xff09; 3、顯示圖片在label上 0&#xff09;直接利用QPixmap顯示圖像 1&#xff09;顯示彩色圖 彩色圖顯示色調不正常——opencv&#xff08;BGR&#xff09;QT(RGB)需要進行…

[Django]SE項目回憶錄(二)-注冊/登錄功能的實現及細節

該項目中提供了注冊和登錄兩部分功能&#xff0c;功能描述如下&#xff1a; 注冊&#xff1a; 允許任何用戶進行學生身份的注冊。 教師用戶預先已經保存在數據庫中&#xff0c;不允許以游客身份注冊新的教師用戶。 注冊時需要填寫的信息包括&#xff1a; - 用戶名 - 密碼(…

Zip4j開源jar包的簡單使用

因為對項目突然要發送壓縮加密的郵件附件&#xff0c;所以從網上看了一些資料說Zip4j開源框架比較好使&#xff0c;對中文的支持也比較好&#xff0c;所以從網上找了一個代碼案例&#xff01;自己寫了一寫&#xff0c;現在貼出來&#xff0c;方便以后想用的時候好找 1、 1 pack…

【pyqt5】——入門級模板(ui文件+ui轉py文件+邏輯py文件)(消息提示框)

目錄 1、ui文件 2、ui轉py文件 3、邏輯py文件 4、實例 1&#xff09;ui文件——demo.ui 2&#xff09;ui轉py文件——demo.py 3)邏輯py文件——demoLogic.py 4)運行結果 1、ui文件 這個文件是直接通過pyqt5 designer進行設計的&#xff0c;相關配置可見《配置Qt Design…

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

文章目錄前言一、點特征直方圖1.1 PFH1.1.1 法線估計1.1.2 特征計算1.2 FPFH1.3 VFH二、示例2.1 PFH計算2.2 FPFH2.3 VFH前言 點特征直方圖是PCL中非常重要的特征描述子&#xff0c;在點云匹配、分割、重建等任務中起到關鍵作用&#xff0c;可以對剛體變換、點云密度和噪聲均有…

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…