PCL系列3 Octree的使用

2021-09-02 17:45:22 字數 3516 閱讀 6539

1. octree原理介紹

八叉樹(octree)的定義是:若不為空樹的話,樹中任一節點的子節點恰好只會有八個,或零個,也就是子節點不會有0與8以外的數目。那麼,這要用來做什麼?想象乙個立方體,我們最少可以切成多少個相同等分的小立方體?答案就是8個。再想象我們有乙個房間,房間裡某個角落藏著一枚金幣,我們想很快的把金幣找出來,聰明的你會怎麼做?我們可以把房間當成乙個立方體,先切成八個小立方體,然後排除掉沒有放任何東西的小立方體,再把有可能藏金幣的小立方體繼續切八等份….如此下去,平均在log8(房間內的所有物品數)的時間內就可找到金幣。因此,八叉樹就是用在3d空間中的場景管理,可以很快地知道物體在3d場景中的位置,或偵測與其它物體是否有碰撞以及是否在可視範圍內。

1.2實現八叉樹的原理:

(1). 設定最大遞迴深度。

(2). 找出場景的最大尺寸,並以此尺寸建立第乙個立方體。

(3). 依序將單位元元素丟入能被包含且沒有子節點的立方體。

(4). 若沒達到最大遞迴深度,就進行細分八等份,再將該立方體所裝的單位元元素全部分擔給八個子立方體。

(5). 若發現子立方體所分配到的單位元元素數量不為零且跟父立方體是一樣的,則該子立方體停止細分,因為跟據空間分割理論,細分的空間所得到的分配必定較少,若是一樣數目,則再怎麼切數目還是一樣,會造成無窮切割的情形。

(6). 重複3,直到達到最大遞迴深度。

2. 示例**

#include

//檔案輸入輸出

#include

//octree相關定義

#include

//vtk視覺化相關定義

#include

//點型別相關定義

#include

#include

intmain()

//2.原始點雲著色

for(size_t i =

0; i < cloud->points.

size()

;++i)

//3.建立octree例項物件

float resolution =

0.03f

;//設定octree體素解析度

pcl:

:octree:

:octreepointcloudsearch

:pointxyzrgb>

octree

(resolution)

;//建立octree物件

octree.

setinputcloud

(cloud)

;//傳入需要建立kdtree的點雲指標

octree.

addpointsfrominputcloud()

;//構建octree

體素內近鄰搜尋

pcl:

:pointxyzrgb searchpoint1 = cloud->points[

1250];

//設定查詢點

std:

:vector<

int> pointidxvec;

//儲存體素近鄰搜尋的結果向量

if(octree.

voxelsearch

(searchpoint1, pointidxvec))}

近鄰搜尋

pcl:

:pointxyzrgb searchpoint2 = cloud->points[

3000];

//設定查詢點

int k =

200;

std:

:vector<

int> pointidxnknsearch;

//儲存k近鄰點的索引結果

std:

:vector<

float

> pointnknsquareddistance;

//儲存每個近鄰點與查詢點之間的歐式距離平方

std:

:cout <<

"k nearest neighbor search at ("

<< searchpoint2.x

<<

" "<< searchpoint2.y

<<

" "<< searchpoint2.z

<<

") with k="

<< k << std:

:endl;

if(octree.

nearestksearch

(searchpoint2, k, pointidxnknsearch, pointnknsquareddistance)

>0)

} std:

:cout <<

"k = 200近鄰點個數:"

<< pointidxnknsearch.

size()

<< endl;

半徑內近鄰搜尋

pcl:

:pointxyzrgb searchpoint3 = cloud->points[

6500];

//設定查詢點

std:

:vector<

int> pointidxradiussearch;

//儲存每個近鄰點的索引

std:

:vector<

float

> pointradiussquareddistance;

//儲存每個近鄰點與查詢點之間的歐式距離平方

float radius =

0.02

;//設定查詢半徑範圍

std:

:cout <<

"neighbors within radius search at ("

<< searchpoint3.x

<<

" "<< searchpoint3.y

<<

" "<< searchpoint3.z

<<

") with radius="

<< radius << std:

:endl;

if(octree.

radiussearch

(searchpoint3, radius, pointidxradiussearch, pointradiussquareddistance)

>0)

} std:

:cout <<

"半徑0.02近鄰點個數: "

<< pointidxradiussearch.

size()

<< endl;

//4.顯示點雲

pcl:

:visualization:

:cloudviewer viewer

("cloud viewer");

viewer.

showcloud

(cloud)

;system

("pause");

return0;

}

3.執行結果

PCL系列2 Kd Tree的使用

include kdtree近鄰搜尋 include 檔案輸入輸出 include 點型別相關定義 include 視覺化相關定義 include include int main 2.原始點雲著色 for size t i 0 i cloud points.size i 3.建立kd tree p...

pcl的初步使用 ROS

ros裡面已經預裝好了pcl,和一些與pcl之間的轉換,我們接下來看看如何在ros裡面使用pcl.總的來說,pcl包含了乙個很重要得到資料結構,叫pointcloud,這是乙個模板類,把點的型別作為模板引數。下面是最重要的在點雲裡面的公共域 header 這個域是pcl pclheader型別和指定...

3D 13 在clion中使用PCL

主要是將pcl加入cmakelist.txt中去,不過我還是遇到了一些問題。比如說cmake沒有真正的將pcl的頭檔案目錄取進去。從原始碼安裝好pcl 1.8後,利用find package pcl required 尋找pcl包,發現能找到,但是include directories pcl in...