Kdtree原理以及 vs Octree


1. Kdtree原理

    Kdtree是一種划分k維數據空間的數據結構,本質也是一顆二叉樹,只不過每個節點的數據都是k維,當k=1時,就是圖1所示的普通二叉樹。

圖1

1)Kdtree的建立

    建立Kdtree實際上是一個不斷划分的過程,首先選擇最sparse的維度(一般通過計算數據在各個維度的方差,選擇方差大的作為本次分割維度),然后找到該維度上的中間點,垂直該維度做第一次划分。此時k維超平面被一分為二,在兩個子平面中再找最sparse的維度,以此類推直到最后一個點也被划分,那么就形了一個不斷二分的樹。

    二維Kdtree的建立過程如圖2所示,首先分別計算x,y方向上數據的方差,得知x方向上的方差最大,所以split域值首先x軸方向;然后根據x軸方向的值2,5,9,4,8,7排序選出中值為7,所以Node-data = (7,2)。這樣,該節點的分割超平面就是通過(7,2)並垂直於split = 0(x軸)的直線x = 7,后面以此類推。

圖2

    三維Kdtree的建立過程:The first split (the red vertical plane) cuts the root cell (white) into two subcells, each of which is then split (by the green horizontal planes) into two subcells. Finally, those four cells are split (by the four blue vertical planes) into two subcells. Since there is no more splitting, the final eight are called leaf cells.

圖3

2)Kdtree的搜索

    搜索一般有:1. 搜索距離search point 一定radius范圍內的所有點;2. 搜索距離search point最近的k個點。

    星號表示要查詢的點(2.1,3.1),通過二叉搜索,順着搜索路徑很快就能找到最鄰近的近似點,也就是葉子節點(2,3)。而找到的葉子節點並不一定就是最鄰近的,最鄰近肯定距離查詢點更近,應該位於以查詢點為圓心且通過葉子節點的圓域內。為了找到真正的最近鄰,還需要進行'回溯'操作:算法沿搜索路徑反向查找是否有距離查詢點更近的數據點。       此例中先從(7,2)點開始進行二叉查找,然后到達(5,4),最后到達(2,3),此時搜索路徑中的節點為<(7,2),(5,4),(2,3)>,首先以(2,3)作為當前最近鄰點,計算其到查詢點(2.1,3.1)的距離為0.1414,然后回溯到其父節點(5,4),並判斷在該父節點的其他子節點空間中是否有距離查詢點更近的數據點。以(2.1,3.1)為圓心,以0.1414為半徑畫圓,如圖4所示。發現該圓並不和超平面y = 4交割,因此不用進入(5,4)節點右子空間中去搜索。再回溯到(7,2),以(2.1,3.1)為圓心,以0.1414為半徑的圓更不會與x = 7超平面交割,因此不用進入(7,2)右子空間進行查找。至此,搜索路徑中的節點已經全部回溯完,結束整個搜索,返回最近鄰點(2,3),最近距離為0.1414。

圖4

    一個復雜點了例子如查找點為(2,4.5),同樣先進行二叉查找,先從(7,2)查找到(5,4)節點,在進行查找時是由y = 4為分割超平面的,由於查找點為y值為4.5,因此進入右子空間查找到(4,7),形成搜索路徑<(7,2),(5,4),(4,7)>,取(4,7)為當前最近鄰點,計算其與目標查找點的距離為3.202。然后回溯到(5,4),計算其與查找點之間的距離為3.041。以(2,4.5)為圓心,以3.041為半徑作圓,如圖5所示。可見該圓和y = 4超平面交割,所以需要進入(5,4)左子空間進行查找。此時需將(2,3)節點加入搜索路徑中得<(7,2),(2,3)>。回溯至(2,3)葉子節點,(2,3)距離(2,4.5)比(5,4)要近,所以最近鄰點更新為(2,3),最近距離更新為1.5。回溯至(7,2),以(2,4.5)為圓心1.5為半徑作圓,並不和x = 7分割超平面交割,如圖6所示。至此,搜索路徑回溯完,返回最近鄰點(2,3),最近距離1.5。

圖5


圖6

2. Kdtree vs Octree

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM