楊 杰,溫小榮*,汪求來,葉金盛
(1.南京林業(yè)大學(xué) 南方現(xiàn)代林業(yè)協(xié)同創(chuàng)新中心,江蘇 南京 210037;2.南京林業(yè)大學(xué) 林學(xué)院,江蘇 南京 210037;3.廣東省林業(yè)調(diào)查規(guī)劃院,廣東 廣州 510520)
經(jīng)過近50 a的研究,樹木建模已廣泛應(yīng)用于多個(gè)領(lǐng)域的活動(dòng)中,如電腦游戲和林業(yè)信息化。不斷地提高樹木建模的精度,可以增加游戲場景的沉浸感;同時(shí),又極大地促進(jìn)林業(yè)信息化,實(shí)現(xiàn)精準(zhǔn)林業(yè)[1-2]。激光雷達(dá)技術(shù)(light detection and ranging,LiDAR)正逐步成為林業(yè)調(diào)查的重要手段,其掃描得到的點(diǎn)云數(shù)據(jù)具有精度高、時(shí)效性好等特點(diǎn),因而成為林業(yè)信息化中的研究熱點(diǎn)[3-4]。點(diǎn)云數(shù)據(jù)可把現(xiàn)實(shí)世界原子化,是將現(xiàn)實(shí)世界中以大量且密集的點(diǎn)的形式將被測量區(qū)域內(nèi)物體的表面表達(dá)出來,因此通過高精度的點(diǎn)云亦可以還原現(xiàn)實(shí)世界,通過研究某一研究目標(biāo)在點(diǎn)云中的信息來反演其現(xiàn)實(shí)世界的信息[5],利用點(diǎn)云數(shù)據(jù)進(jìn)行樹木建模的意義也正是如此。通過點(diǎn)云數(shù)據(jù)進(jìn)行測量與傳統(tǒng)的人工測量相比,生物量、產(chǎn)量、葉面積指數(shù)等相關(guān)參數(shù)獲得的更加準(zhǔn)確[6]?;邳c(diǎn)云、基于圖像、基于規(guī)則或過程和基于草圖共同構(gòu)成現(xiàn)在樹木建模的4大主要方法。
單木建模由枝干建模和葉片建模兩部分構(gòu)成,其中,枝干模型表達(dá)的一種方法是骨架,此外比較常見的方法還有Delaunay三角網(wǎng)等。石銀濤[7]指出,現(xiàn)有的研究中點(diǎn)云樹木枝干模型骨架的提取算法主要基于3類——體素空間(voxel space,VS)、點(diǎn)云收縮(point clouds contract,PCC)、幾何特征(geometrical characteristic,GC),其中,GC算法僅在運(yùn)算效率中未達(dá)到最優(yōu),次于PCC算法,而在此外的各個(gè)方面均達(dá)到最優(yōu)或并列最優(yōu),包括處理細(xì)小枝、模型拓?fù)?、整體效果、處理鄰近分支和中心偏差。以犧牲較小的時(shí)間代價(jià)換取更高的建模精度滿足大部分研究者的研究需求,以中國知網(wǎng)為例,搜索關(guān)鍵詞“點(diǎn)云樹木建?!?,最早一篇發(fā)表于2011年12月1日,截至2021年10月24日共計(jì)40篇文章中,排除4篇文獻(xiàn)綜述、未直接指明骨架提取方法(包括直接使用三維建模軟件的3篇)、非骨架提取(17篇)的文獻(xiàn)以外,剩余16篇中,有2篇是VS算法,1篇是PCC算法,其余共13篇均為GC算法,可見其研究與應(yīng)用之多。
GC算法的思路是將枝干點(diǎn)云按照一定規(guī)則分成若干bins,再將每個(gè)bins通過聚類拆分成1個(gè)或多個(gè)bin,對(duì)每一個(gè)bin求出中心點(diǎn),按照真實(shí)關(guān)系將點(diǎn)連接即可得到枝干點(diǎn)云[8],bin有文獻(xiàn)譯作枝干段,但bins卻無對(duì)應(yīng)的翻譯,根據(jù)實(shí)際意義可解釋為“枝干段集”,bins、bin與最后建立的骨架的示意圖如圖1(a)-圖1(c)所示。
圖1 bins、bin和枝干骨架
目前GC算法采用的規(guī)則分為2種:以根節(jié)點(diǎn)距離相似歸類和以高度歸類。生態(tài)學(xué)研究表明,樹木在水分養(yǎng)分的傳輸中趨向使用最短路徑來達(dá)到資源配置的最優(yōu)化[9-10],而以根節(jié)點(diǎn)距離相似歸類的思想正是量化各點(diǎn)與根節(jié)點(diǎn)的最短路徑長度按距離“相似”地劃分成各個(gè)區(qū)域,以此作為bins。其中,根節(jié)點(diǎn)是指經(jīng)過校正后的枝干點(diǎn)云中z軸高度最低的點(diǎn),它代表在地面之上樹根的位置;相似指的是按照距離的大小進(jìn)行分組。而以高度歸類是直接以根節(jié)點(diǎn)和樹冠最高點(diǎn)的高度差直接分段。記N為bins分成的數(shù)量,分別取N=20、50、100比較2種規(guī)則分段后的結(jié)果以及N=100時(shí)得到的骨架,如圖2所示。
由圖2可以看出,以根節(jié)點(diǎn)距離相似歸類區(qū)別于以高度歸類之處在于以根節(jié)點(diǎn)距離相似歸類得到的bins以根節(jié)點(diǎn)向外呈現(xiàn)輻射狀;當(dāng)N增大時(shí),根處的bins的形狀呈現(xiàn)單側(cè)塌陷,并在N充分大時(shí)直觀上不閉合,這將會(huì)導(dǎo)致根節(jié)點(diǎn)明顯偏移樹木根部中心位置,產(chǎn)生這一問題原因是點(diǎn)云獲得的是樹木表面的信息,因此根節(jié)點(diǎn)在樹木表面上,并非樹根處的中心位置,現(xiàn)已有研究對(duì)這一問題進(jìn)行了改進(jìn)[11],然而目前很多使用了以根節(jié)點(diǎn)距離相似歸類方法的文獻(xiàn)未注意到這一問題,未改進(jìn)時(shí)在根節(jié)點(diǎn)處存在明顯的劣勢,但以N=100時(shí)的2種規(guī)則建立出來的骨架進(jìn)行對(duì)比,可見其在枝條分叉處的處理更加合理,分叉處得到的骨架中心點(diǎn)更靠近枝條真實(shí)的中心位置,有利于后續(xù)骨架的優(yōu)化。
圖2 2種規(guī)則的bins效果及骨架建立效果
現(xiàn)有的大多數(shù)文章雖然介紹了以根節(jié)點(diǎn)距離相似歸類并提及了Dijkstra算法求解最短路徑,但通過前面介紹的2種規(guī)則得到的bin的差異,可以判斷出其中由很多文獻(xiàn)仍然使用的是以高度歸類的規(guī)則來建立骨架,一方面可能是由于采用了不合適的數(shù)據(jù)結(jié)構(gòu),另一方面是Dijkstra算法本身計(jì)算復(fù)雜度高,因而在處理海量點(diǎn)云時(shí)執(zhí)行速度較慢。
本研究主要針對(duì)基于幾何特征的樹木枝干點(diǎn)云骨架提取時(shí),考慮到枝干點(diǎn)云數(shù)據(jù)量大,討論了圖的表達(dá)方式,對(duì)經(jīng)典的最短路徑算法及其改進(jìn)的適用性進(jìn)行了討論,并對(duì)適用的最短路徑的算法各自作一定的改進(jìn)以適用于枝干點(diǎn)云且滿足內(nèi)存節(jié)省與快速處理的需求。試驗(yàn)使用C++編程實(shí)現(xiàn),以真實(shí)樹木點(diǎn)云比較若干算法的實(shí)際效果。
圖G=(V,E)的典型表示方法包括鄰接矩陣與鄰接表2種方法[12-13],性能復(fù)雜度如表1所示。
表1 性能復(fù)雜度對(duì)比
對(duì)于枝干點(diǎn)云,若點(diǎn)數(shù)非常大,采用鄰接矩陣會(huì)對(duì)內(nèi)存的需求非常大,以本研究將使用的楊樹的點(diǎn)云為例,枝葉分離后得到的枝干點(diǎn)云點(diǎn)數(shù)為|V|=198 500(后文使用|P|),鄰接矩陣所需的理論內(nèi)存為198 5002×sizeof(double)≈293.57 GB,這遠(yuǎn)遠(yuǎn)超過了一般設(shè)備的承受范圍,而且由于并不是任意兩點(diǎn)均可達(dá),事實(shí)上每一個(gè)點(diǎn)只和本身附近很小范圍內(nèi)的點(diǎn)可達(dá),因而該矩陣中很多元素都是∞,占用了過多不必要的空間。
求解圖的最短路徑問題的常用算法包括Floyd算法、Dijkstra算法和Bellman-Ford算法。由于Floyd算法中需要存儲(chǔ)最短距離矩陣所需空間為T(|V|2),因而不適用于海量點(diǎn)云,不再進(jìn)一步討論。另外2種算法適用于海量點(diǎn)云,但仍有一定的改進(jìn)空間,對(duì)于Dijkstra算法,用堆進(jìn)行優(yōu)化;對(duì)于Bellman-Ford算法,用隊(duì)列進(jìn)行優(yōu)化得到SPFA算法,而SPFA算法可進(jìn)一步優(yōu)化,可采用3種策略,包括Small Label First(SLF)、Large Label Last(LLL)、SLF與LLL結(jié)合(SLF+LLL)[14],若干算法的時(shí)間復(fù)雜度如表2所示。
表2 最短路徑算法時(shí)間復(fù)雜度對(duì)比
由于從LiDAR設(shè)備獲取的枝干點(diǎn)云是以無序點(diǎn)云的形式保存的,點(diǎn)云中的點(diǎn)的序號(hào)并不能反映出一定的規(guī)律。由枝干點(diǎn)云建立的邊是每一個(gè)點(diǎn)與其附近一定范圍內(nèi)的點(diǎn)的直線距離,并不是負(fù)數(shù),因而不存在負(fù)權(quán)邊。這些算法現(xiàn)有的實(shí)現(xiàn)中所使用的鄰接表并不全都滿足可處理無向圖,無須考慮負(fù)權(quán)邊或盡可能節(jié)省內(nèi)存使用,即仍然使用鄰接矩陣實(shí)現(xiàn),或應(yīng)用于點(diǎn)云時(shí)算法有不必要的判斷增加了時(shí)間消耗,或采用的鄰接表存放的數(shù)據(jù)結(jié)構(gòu)不夠精練,因而在獲取枝干點(diǎn)云的最短路徑方面,若干算法需要進(jìn)一步地改進(jìn)。
首先,對(duì)獲得的樹木點(diǎn)云枝葉分離,利用kd-tree以半徑R進(jìn)行最近鄰檢索,得到枝干點(diǎn)云,半徑的選取應(yīng)當(dāng)以保證枝干上的每個(gè)點(diǎn)都應(yīng)當(dāng)至少有一個(gè)鄰近點(diǎn)且足夠小為宜。其次,使用kd-tree以半徑為r進(jìn)行最鄰近檢索以獲取圖,其中,務(wù)必保證r≥R,且考慮到枝干點(diǎn)云中每個(gè)點(diǎn)只能和附近一定范圍內(nèi)的點(diǎn)可達(dá),因而r不宜太大。表3給出使用的符號(hào)及其含義,獲取邊和參數(shù)初始化的算法如算法1所示。
表3 符號(hào)及其含義
算法1 鄰接表的建立及參數(shù)初始化
Algorithm 1 Establishment of adjacency table and parameter initialization
E.resize(|P|)
D.resize(|P|)
F.resize(|P|)
kdtree.init()
kdtree.setInputCloud(P);
fori:=1→|P| do
Si(r):=kdtree.radiusSearch(Pi,r)
foreach 序號(hào)j∈Si(r) do
end for
ifi≠xthen
Di:=+inf
Fi:=NULL
else
Di:=0
Fi:=i
end if
end for
2.2.1 Dijkstra算法 Dijkstra算法基于廣度優(yōu)先搜索思想,從選定的源節(jié)點(diǎn)開始,跟蹤每個(gè)節(jié)點(diǎn)到源節(jié)點(diǎn)當(dāng)前已知的最短路徑距離,如果發(fā)現(xiàn)比當(dāng)前更短的路徑,則更新最短路徑距離值。一旦找到源節(jié)點(diǎn)和某一節(jié)點(diǎn)間的最短路徑,就標(biāo)記該節(jié)點(diǎn)為“已訪問”,并在路徑表中添加到該節(jié)點(diǎn)的最新路徑。持續(xù)該過程直至所有節(jié)點(diǎn)都在路徑表中有路徑,此時(shí)的路徑表中每一條路徑遵循了源節(jié)點(diǎn)可能到達(dá)的每個(gè)節(jié)點(diǎn)的最短路徑。
實(shí)際對(duì)路徑的存儲(chǔ)時(shí),只需存放與每一節(jié)點(diǎn)相連接的那一段路即可。一方面,由前述的r≥R保證,圖勢必是連通的,通過逆向查找就可以回溯得到完整路徑;另一方面,能夠節(jié)省空間并提升算法的執(zhí)行速度。
算法2 適用于枝干點(diǎn)云的Dijkstra算法
Algorithm 2 Dijkstra’s algorithm for branch point cloud
初始化標(biāo)記序列B,其中Bi:=false,i=1,2,…,|P|
fori:=1→|P| do
v:=NULL
forj:=1→|P| do
ifBj=false and (v=NULL orDv>Dj) then
v←j
end if
end for
ifv=NULL then
break
end if
Bv←true
foreach 元組e∈Evdo
w:=e[0]
d:=e[1]
ifBw=false andDw>Dv+dthen
Dw←Dv+d
Fw←v
end if
end for
end for
2.2.2 堆優(yōu)化的Dijkstra算法 Dijkstra算法的一個(gè)缺點(diǎn)是遍歷計(jì)算的節(jié)點(diǎn)很多,因而效率低,尤其在面對(duì)節(jié)點(diǎn)多或者邊多的大圖的處理時(shí)。堆(heap)優(yōu)化是利用1個(gè)每次彈出其中最小元素的優(yōu)先隊(duì)列(priority queue)來代替最近距離的找查,堆優(yōu)化的Dijkstra可以大幅節(jié)約時(shí)間開銷。
算法3 適用于枝干點(diǎn)云的堆優(yōu)化的Dijkstra算法
Algorithm 3 Dijkstra’s Algorithm implemented with a Min-Heap for branch point cloud
初始化優(yōu)先隊(duì)列Q,比較方式為升序
Q.push ((x,0))
whileQ不為空 do
q:=Q.top()
Q.pop()
v:=q[0]
ifDv continue end if foreach 元組e∈Evdo w:=e[0] d:=e[1] ifDw>Dv+dthen Dw←Dv+d Fw←v Q.push((w,Dw)) end if end for end while 2.2.3 Bellman-Ford算法 Bellman-Ford算法(或稱Bellman-Ford-Moore算法、距離向量算法)通過簡單地對(duì)所有邊松弛,以自下而上的方式搜尋最短路徑。首先尋找路徑中只有1條邊的距離,之后增加路徑長度以找到所有可能的解決方案。 算法4 適用于枝干點(diǎn)云的Bellman-Ford算法 Algorithm 4 Bellman-Ford algorithm for branch point cloud while true do b:=false fori:=1→|P| do foreach 元組e∈Eido w:=e[0] d:=e[1] ifDi≠+inf andDw>Di+dthen Dw←Di+d Fw←i end if end for end for end while 2.2.4 SPFA算法 SPFA(shortest path faster algorithm)算法采用對(duì)1個(gè)隊(duì)列進(jìn)行維護(hù)以使在1個(gè)節(jié)點(diǎn)當(dāng)前的最短路徑更新后無須立即更新其他節(jié)點(diǎn),大大減少了重復(fù)的操作次數(shù)。但是在最壞情況下,每一個(gè)節(jié)點(diǎn)都入隊(duì)|V|-1次,此時(shí)也就退化成了Bellman-Ford算法[15-16]。 算法5 適用于枝干點(diǎn)云的SPFA算法 Algorithm 5 SPFA for branch point cloud 初始化標(biāo)記序列B,其中Bi:=false,i=1,2,…,|P| Bx←true 初始化隊(duì)列Q′ Q′.push(x) whileQ′不為空 do v:=Q′.front() Q′.pop() foreach 元組e∈Evdo w:=e[0] d:=e[1] ifDw>Dv+dthen Dw←Dv+d Fw←v ifBw=false then Q′.push(w) Bw←true end if end if end for end while 2.2.5 SPFA算法的3種優(yōu)化 SLF策略即把較小的元素提前,利用雙端隊(duì)列,如果新入隊(duì)的元素比隊(duì)首的元素更小,則加入到隊(duì)首,否則排到隊(duì)尾。 LLL策略則通過比較隊(duì)列中元素的最短路徑距離的平均值和待壓入隊(duì)列的元素的當(dāng)前最短路徑長度,如果大于平均值,則壓入隊(duì)尾。 SLF與LLL策略并不沖突,因而又可以同時(shí)被采用。在某些圖求解最短路徑的問題上,SPFA算法的SLF優(yōu)化比SPFA算法快10%~20%,而SPFA算法的SLF+LLL優(yōu)化甚至能比SPFA算法快近50%。 算法6 適用于枝干點(diǎn)云的SPFA算法的SLF優(yōu)化 Algorithm 6 The SLF algorithm for branch point cloud 初始化標(biāo)記序列B,其中Bi:=false,i=1,2,…,|P| Bx←true 初始化雙端隊(duì)列Q″ Q″.push_back(x) whileQ″不為空 do v:=Q″.front() Q″.pop_front() Bv←false foreach元組e∈Evdo w:=e[0] d:=e[1] ifDw>Dv+dthen Dw←Dv+d Fw←v ifBw=false then Bw←true ifQ″不為空 andDw Q″.push_front(w) else Q″.push_back(w) end if end if end if end for end while 算法7 適用于枝干點(diǎn)云的SPFA算法的LLL優(yōu)化 Algorithm 7 The LLL algorithm for branch point cloud 初始化標(biāo)記序列B,其中Bi:=false,i=1,2,…,|P| Bx:=true 初始化隊(duì)列Q′ Q′.push(x) dQ′:=0 %隊(duì)列中所有序號(hào)的最短路徑距離總和 nQ′:=1 %隊(duì)列中序號(hào)個(gè)數(shù) whileQ′不為空 do v:=Q′.front() whileDv·nQ′>dQ′do Q′.pop() Q′.push(v) v←Q′.front() end while Q′.pop() nQ′←nQ′-1 dQ′←dQ′-Dv Bv←true foreach元組e∈Evdo w:=e[0] d:=e[1] ifDw>Dv+dthen Dw←Dv+d Fw←v ifBw=false then Q′.push(w) nQ′←nQ′+1 dQ′←dQ′+Dw Bw←true end if end if end for end while 算法8 適用于枝干點(diǎn)云的SPFA算法的SLF+LLL優(yōu)化 Algorithm 8 The (combined) SLF/LLL algorithm for branch point cloud 初始化標(biāo)記序列B,其中Bi:=false,i=1,2,…,|P| Bx:=true 初始化雙端隊(duì)列Q″ Q″.push_back(x) dQ′:=0 %隊(duì)列中所有序號(hào)的最短路徑距離總和 nQ′:=1 %隊(duì)列中序號(hào)個(gè)數(shù) whileQ″不為空 do v:=Q″.front() Q″.pop_front() ifDv·nQ′>dQ′do Q″.push(v) continue end if nQ′←nQ′-1 dQ′←dQ′-Dv Bv←true foreach元組e∈Evdo w:=e[0] d:=e[1] ifDw>Dv+dthen Dw←Dv+d Fw←v ifBw=false then ifQ″不為空 andDw Q″.push_front(w) else Q″.push_back(w) end if nQ′←nQ′+1 dQ′←dQ′+Dw Bw←true end if end if end for end while 本試驗(yàn)使用的樹木位于江蘇省宿遷市泗洪縣陳圩林場馬浪湖分場(33°15′N,118°18′E),樹種均為美洲黑楊(Populusdeltoides)中南林797楊,使用RIEGL VZ-400i地基激光雷達(dá)掃描儀對(duì)樹木所在樣地進(jìn)行多站掃描[17],掃描模式設(shè)置為Panorama40,詳細(xì)參數(shù)如表4所示。 表4 RIEGL VZ-400i掃描模式Panorama40 將項(xiàng)目文件從設(shè)備導(dǎo)出,使用RiSCAN Pro 2.7多站拼接后導(dǎo)出為las文件格式,然后在LiDAR360軟件中去噪、去除地面點(diǎn)、根據(jù)地面點(diǎn)歸一化后導(dǎo)出las文件,導(dǎo)入到Cloud Compare中先切成單排點(diǎn)云后再進(jìn)行單木分割并將每木點(diǎn)云導(dǎo)出成pcd文件格式得到了本試驗(yàn)所用的樹木點(diǎn)云,最后,在Visual Studio 2019+PCL 1.11.0內(nèi)去除重復(fù)點(diǎn),將單木點(diǎn)云進(jìn)行適當(dāng)變換使樹干點(diǎn)云的根部切面與平面xOy盡可能重合,所有點(diǎn)均在平面xOy上或上方,并使根部中心盡可能靠近原點(diǎn)(0,0,0)處,以此作為試驗(yàn)數(shù)據(jù),如圖3所示。 圖3 試驗(yàn)數(shù)據(jù) 試驗(yàn)環(huán)境如表5所示。 表5 試驗(yàn)環(huán)境 對(duì)試驗(yàn)所用的樹木點(diǎn)云以參數(shù)R=0.05枝葉分離得到枝干點(diǎn)云,此時(shí)的枝干點(diǎn)云點(diǎn)數(shù)|P|=198,500,按照算法1以參數(shù)x=0構(gòu)建鄰接表和初始化需要的參數(shù)。比較枝干點(diǎn)云獲取最短路徑長度進(jìn)行優(yōu)化的若干算法的實(shí)際運(yùn)行時(shí)長。以r=R,r=2R,r=3R并各自進(jìn)行10次試驗(yàn)測試,結(jié)果如表6所示。 表6 若干算法的執(zhí)行時(shí)間 由表6可知,采用鄰接表所使用的內(nèi)存遠(yuǎn)遠(yuǎn)小于鄰接矩陣所需要的。同樣是鄰接表來表示圖,傳統(tǒng)使用的Dijkstra算法速度遠(yuǎn)遠(yuǎn)慢于其他所有算法,而SPFA及其優(yōu)化相比之下更快。在求解枝干點(diǎn)云的最短路徑問題上,SPFA的3種優(yōu)化并不如在某些圖的求解上非常顯著且穩(wěn)定地比SPFA更快,因此,在枝干點(diǎn)云獲取最短路徑長度方面,選用適配后的SPFA算法是理想方案,對(duì)SPFA的3種改進(jìn)則不一定需要。圖4是建立的最短路徑的在根部附近的展示,為了便于展示,調(diào)整了枝干點(diǎn)云的觀察角度。 圖4 根部附近的最短路徑 本研究簡要介紹了樹木建模中利用點(diǎn)云以及基于幾何特征的枝干點(diǎn)云的骨架提取的意義,對(duì)比了以根節(jié)點(diǎn)距離相似歸類和以高度歸類2種規(guī)則的優(yōu)劣,前者在樹干分叉處魯棒性較好,但現(xiàn)有研究中大多采用的Dijkstra算法處理枝干點(diǎn)云的速度較慢,抑或采用了不合適的表達(dá)圖的數(shù)據(jù)結(jié)構(gòu)因而實(shí)際使用的較少。針對(duì)這一現(xiàn)象,本研究首先采用了鄰接表的形式作為圖的數(shù)據(jù)結(jié)構(gòu)的表達(dá),并將現(xiàn)有的若干求解最短路徑的算法進(jìn)行改進(jìn)以應(yīng)用于枝干點(diǎn)云,結(jié)果表明,采用枝干點(diǎn)云的SPFA算法是理想方案,大大減少了執(zhí)行時(shí)間。本研究能夠?yàn)榫?xì)化點(diǎn)云樹木建模提供一定幫助。3 試驗(yàn)驗(yàn)證
3.1 數(shù)據(jù)來源與預(yù)處理
3.2 試驗(yàn)環(huán)境
3.3 結(jié)果與分析
4 結(jié)論