基於pcl qt的大規模點雲動態顯示的一些小心得

2021-10-25 08:50:35 字數 3250 閱讀 5272

點雲視覺化,尤其大規模視覺化真是個折磨人的事。自然也是酸甜苦辣各種交加。今日就最近踩坑做乙個記錄,給後來人一些參考。

點雲動態顯示需要解決的問題是,將點雲採集裝置高速採集的點雲實時顯示在介面中。需要實現的效果如圖所示,這片測試點雲還比較小,有256000個點:

圖1之前我在最初調試點雲動態顯示時寫過一篇文章,《兩種方式實現pcl+qt下動態增加點雲》。其中談到了兩種方法。其中方法2採用點雲指標是比較輕鬆簡便的,對於點雲數目不多時比較推薦。然而對於大規模點雲,每次都要把所有顯示的點雲重新重新整理一遍,這樣十分消耗資源。因此在大規模點雲顯示時更加推薦第一種方法。當然,第一種方法也是坑很多的,以下來談談其中的坑。

這兒我們做了乙個預定義:

typedef pcl::pointxyzrgb pointt;

typedef pcl::pointcloud pointcloudt;

因為是實時顯示點雲,此處有些類似生產者和消費者問題,也是乙個fifo問題。我們定義乙個佇列來放置點雲:

std::queue <:ptr>

* cloud_queue =

null

;cloud_queue =

new std::queue <:ptr>

;//最後別忘了 delete cloud_queue

點雲生產者會快速生產點雲,這兒我們通過從已載入的點雲讀取點雲模擬點雲的快速產生(首先我們做了乙個延時,讓點雲生產慢一些):

for

(size_t jj =

0; jj < cloud0-

>points.

size()

;++jj)

}

點雲的顯示則是從佇列中不斷讀取點雲。我在主線程中做了乙個定時器(我發現如果再開乙個子執行緒顯示點雲,會出現介面崩潰的現象,目前還沒找到問題《單擊pclvisualizer 類介面,顯示點雲引發異常》)

connect

(this

,&qtselfpcl::sendqueue,

&ccll,

&cloud_collection::loadpointcloud)

;connect

(qutimer,

&qtimer::timeout,

this

,&qtselfpcl::timerqueue)

;connect

(ui.ccltest,

&qpushbutton::pressed,[=]);

void qtselfpcl::

timerqueue()

}

即每過500ms就會自動重新整理畫圖一次。每次都從佇列中pop一塊點雲來,然後裝入vector中,然後繪製。

之所以要裝入vector中,是為了保證每次能夠新增重新整理不同的點雲。實際上pointcloudt::ptr是乙個點雲指標型別,cloudnp_queue裝入的點雲實際上隨著每次的push操作已經把已經裝入的點雲改變了。cloudnp_queue中的每乙個點雲元素都是相同的,vector中所有的點雲實際也是相同的。如果我們每次把vector中所有的點雲都重新整理一遍,會變成如圖2下的效果:

圖2把vector中全部的元素再重新整理一遍的**如下:

void qtselfpcl::

timerqueue()

viewer-

>

resetcamera()

;//自動調整視角

ui.qvtkwidget-

>

update();}}

這也就是說明,已經畫addpointcloud的點雲,只要不去重新整理它,即使它對應的點雲變數變化了,也不會影響顯示。因此要重視updatepointcloud的用法。

那麼問題又來了,如果點雲的產生非常快,是高速產生點雲呢?比如我們用下面所示**模擬點雲的產生:

for

(size_t jj =

0; jj < cloud0-

>points.

size()

;++jj)

}

這個時候就會出現如圖2所示。原因是點雲還沒來得及繪製,就已經產生完了,並且儲存在cloud_queue佇列中。但由於存入的是點雲指標cloud_np,點雲指標每次都會改變(我在另外一篇部落格中談到了這個問題《c++ vector的型別為指標型別時要注意指標所指向的元素有無發生變化,否則vector中的元素會改變》),因此佇列中的點雲都是相同,都為push進入的最後一片點雲,那麼如何解決這個問題呢?

pointcloudt::ptr 實際上是pointcloudt的指標型別。在queue或vector中存放指標型別實際上十分容易出錯。但pcl visualizer類畫圖必須用指標型別畫圖,此處又有些麻煩。這種方法**如下:

定義pointcloudt佇列:

std::queue 

* cloudnp_queue =

null

cloudnp_queue =

new std::queue

;

高速採集點雲:

for

(size_t jj =

0; jj < cloud0-

>points.

size()

;++jj)

}

繪製點雲:

void qtselfpcl::

timerqueue()

viewer-

>

resetcamera()

;//自動調整視角

ui.qvtkwidget-

>

update();}}

這樣就可以顯示如圖1所示的效果了。

(1)採用本文所談到的方法,每次只在檢視中重新整理新得到的點雲,當然顏色深度資訊每次也只重新整理了當下得到的點雲。可以在點雲採集完成後再一起重新整理。

(2)處理pointcloudt::ptr型別的點雲以及其對應的vector,queue要慎重,警惕重新整理指標所指的內容而改變vector或queue中其它的元素。

大規模資料作成時的注意點。

有時候測試大規模資料,300萬條。這時有幾點是我們需要注意的。1.對作成的資料,選擇乙個字段設定上特殊的值。通過這個特殊值來判斷表中的資料是這次大規模的測試資料,還是已有資料。同時也方便將來刪除。2.確認資料的有效性。比如,db中有的字段是加密後的字段,程式中會將這個資料解密。如果無法解密則會報錯,...

鐘博 雲安全是雲計算大規模應用的前提

本文講的是鐘博 雲安全是雲計算大規模應用的前提,5月20日訊息,第三屆 雲計算大會今天繼續在北京國家會議中心舉行。在今天下午進行的 雲計算環境下的資訊保安專題論壇中,衛士通總經理助理兼戰略合作部總經理鐘博做了 雲環境下的安全體系架構 主題演講。他表示,雲計算時代的到來是無法迴避的事實,雲的設計要安全...

基於區域增長的點雲分割

region growing segmentation 基於區域增長的點雲分割 pcl regiongrowing 該類在pcl 1.7.0才有的 pcl normalestimation 計算法向量 演算法思路 選擇種子點 在當前點集a中選擇有最小曲率的點加入種子點集 區域增長 尋找種子點的鄰域點...