誰是我鄰居 kdTree OcTree

2021-07-24 15:30:48 字數 2575 閱讀 9328

由於分割工作需要對點雲的鄰近點進行操作,不斷對比和訪問某個點的鄰居,所以決定點雲的相鄰關係是非常重要的。對於scan來說,鄰居關係是天然的。但對於很多雜亂點雲,或者濾波,分割後的點雲來說,鄰居關係就已經被破壞了。確定乙個點雲之間的相鄰關係可以通過「樹」來完成,目前比較主流的方法包括:kdtree和octree,這兩種方法各有特點。

關於kdtree到底是怎麼工作的這裡有非常詳細的說明,我不再贅述。但是kdtree實際上包括兩個部分:1.建立kdtree,2.在kdtree中查詢。建立kdtree實際上是乙個不斷劃分的過程,首先選擇最sparse的維度,然後找到該維度上的中間點,垂直該維度做第一次劃分。此時k維超平面被一分為二,在兩個子平面中再找最sparse的維度,依次類推知道最後乙個點也被劃分。那麼就形了乙個不斷二分的樹。如圖所示。

顯然,一般情況下乙個點的鄰近點只需要在其父節點和子節點中搜尋即可,大大縮小了鄰近點的搜尋規模。並且kdtree可以有效的對插入點進行判斷其最近點在哪個位置。對於低層次視覺來說kdtree演算法是非常重要的。在很多情況下需要給出某個點,再查k臨近點的編號,或者差某半徑範圍內的點。pcl已經實現了kdtree演算法,其呼叫介面如下:

#include #include 

//建立kdtree 結構

pcl::kdtreeflannkdtree;

//傳入點雲

kdtree.setinputcloud (cloud);

//設定輸入點

pcl::pointxyz searchpoint;

//k鄰近搜尋

int k = 10

;

//設定兩個容器,第乙個放點的標號,第二個點到searchpoint的距離

std::vectorpointidxnknsearch(k);

std::vector

pointnknsquareddistance(k);

//進行搜尋,注意,此函式有返回值》0為找到,<0則沒找到

kdtree.nearestksearch (searchpoint, k, pointidxnknsearch, pointnknsquareddistance)

//基於距離的搜尋

////

兩個未知大小的容器,作用同上

std::vectorpointidxradiussearch;

std::vector

pointradiussquareddistance;

//搜尋半徑

float radius = 3;

//搜尋,效果同上

kdtree.radiussearch (searchpoint, radius, pointidxradiussearch, pointradiussquareddistance)

顯然,我們還需要乙個演算法把idx裡的點雲資料提取出來進行重新著色之類的工作,**可以寫作:

pcl::pointcloud::ptr npoints(new pcl::pointcloud);

npoints->height=1

; npoints->width=searchindice.size();

npoints->resize (searchindice.size());

//注意此清空操作非常極其以及特別重要,否則npoints中會有莫名奇妙的點。

npoints->clear();

int pointnum = 0

;

for(int i=0;ii)

pcl::visualization::pointcloudcolorhandlercustom

npoints_color_handler (npoints, 0, 255, 0

); viewer->addpointcloud(npoints,npoints_color_handler,"

npoints");

viewer->setpointcloudrenderingproperties (pcl::visualization::pcl_visualizer_point_size, 5, "

npoints

");

octree是一種更容易理解也更自然的思想。對於乙個空間,如果某個角落裡有個盒子我們卻不知道在哪兒。但是"神"可以告訴我們這個盒子在或者不在某範圍內,顯而易見的方法就是把空間化成8個卦限,然後詢問在哪個卦限內。再將存在的卦限繼續化成8個。意思大概就是太極生兩儀,兩儀生四象,四象生八卦,就這麼一直劃分下去,最後一定會確定乙個非常小的空間。對於點雲而言,只要將點雲的立方體凸包用octree生成很多很多小的卦限,那麼在相鄰卦限裡的點則為相鄰點。

顯然,對於不同點雲應該採取不同的搜尋策略,如果點雲是疏散的,分布很廣泛,且每什麼規律(如lidar測得的點雲或雙目視覺捕捉的點雲)kdtree能更好的劃分,而octree則很難決定最小立方體應該是多少。太大則乙個立方體裡可能有很多點雲,太小則可能立方體之間連不起來。如果點雲分布非常規整,是某個特定物體的點雲模型,則應該使用octree,因為很容易求解凸包並且點與點之間相對距離無需再次比對父節點和子節點,更加明晰。典型的例子是斯坦福的兔子。

誰是我的客戶?

一直埋頭工作,突然間忽視了這個重要的問題 誰是我的客戶?我們通常理解的客戶是指組織外部的客戶,我們要將我們的工作成果交給他 她,當然工作成果也稱為交付成果,需要令客戶滿意,不然,客戶是不會買帳的。根據工作成果為了令誰滿意,客戶還有其更廣闊的意義。組織內的個體也都有自己的客戶,而且有的,客戶不只乙個。...

昨日我是誰,今日誰是我

每天醒來,常有感慨 昨日我是誰,今日誰是我 我,不過是個侷限了的思維,放開侷限,沒有你,我,他的區別。不過都是一堆資料,經過不同的處理過程,就成了所謂的人我之別。身體,是個軀殼,並不是我。身體中有個處理資料的東西,這就是我,且稱之為靈魂 身體之於靈魂,就像資料之於程式 若我離開身體,別的靈魂進入這個...

我是螳螂,誰是黃雀

我是螳螂,誰是黃雀 2011年06月21日 b b b 我是螳螂,誰是黃雀?b b 江月 b b 很後悔當初沒有聽從朋友的好言相勸,以至於最近耽誤了不少時間和精力不說,還弄得自己豬八戒照鏡子 裡外不是人。b b 不過仔細反思整個過程,之所以到了今天的地步,也不能全怪別人,我自己也有太多失誤的地方。b...