點雲由龐大的數據集組成,這些數據集通過距離、顏色、法線等附加信息來描述空間三維點。此外,點雲能以非常高的速率被創建出來,因此需要占用相當大的存儲資源,一旦點雲需要存儲或者通過速率受限制的通信信道進行傳輸,提供針對這種數據的壓縮方法就變得十分有用。PCL庫提供了點雲壓縮功能,它允許編碼壓縮所有類型的點雲,包括“無序”點雲,它具有無參考點和變化的點尺寸、分辨率、分布密度和點順序等結構特征。而且,底層的octree數據結構允許從幾個輸入源高效地合並點雲數據。
圖1 點雲壓縮示意圖
下面,我們解釋單個點雲和點雲數據流是如何高效壓縮的,在給出的例子中,我們用PCL點雲壓縮技術來壓縮用OpenNIGrabber抓取到的點雲。
代碼:
首先,在PCL(Point Cloud Learning)中國協助發行的書提供光盤的第6章例1文件夾中,打開名為point_cloud_compression.cpp的代碼文件。
解釋說明
下面詳細解析打開的源代碼。從主函數開始,首先創建一個新的SimpleOpenNIViewer實例並調用它的run()方法。
int main(int argc,char **argv) { SimpleOpenNIViewer v; v.run(); return(0); }
在run()函數中,創建PointCloudCompression類的對象來編碼和解碼,這些對象把壓縮配置文件作為配置壓縮算法的參數,所提供的壓縮配置文件為OpenNI兼容設備采集到的點雲預先確定的通用參數集。本例中,使用MED_RES_ONLINE_COMPRESSION_WITH_COLOR配置參數集,它應用5立方毫米的編碼精度並且允許彩色紋理成分編碼,並進一步優化,用於快速在線壓縮。壓縮配置文件的完整列表及其配制方法可以在文件“/io/include/pcl/compression/compression_profiles.h”中找到。在PointCloudCompression構造函數中使用MANUAL_CONFIGURATION屬性就可以手動設置壓縮算法全部參數。
bool showStatistics=true; //設置在標准設備上輸出打印出壓縮結果信息 // 壓縮選項詳見 /io/include/pcl/compression/compression_profiles.h pcl::octree::compression_Profiles_e compressionProfile=pcl::octree::MED_RES_ONLINE_COMPRESSION_WITH_COLOR; // 初始化壓縮與解壓縮對象,其中壓縮對象需要設定壓縮參數選項,解壓縮按照數據源自行判斷 PointCloudEncoder=new pcl::octree::PointCloudCompression<pcl::PointXYZRGBA> (compressionProfile, showStatistics); PointCloudDecoder=new pcl::octree::PointCloudCompression<pcl::PointXYZRGBA> ();
下面的代碼為OpenNI兼容設備實例化一個新的采集器,並且啟動循環回調接口,每從設備獲取一幀數據,就調用回調函數一次,這里的回調函數實現數據壓縮和可視化解壓縮結果。
//創建從 OpenNI獲取點雲的抓取對象 pcl::Grabber* interface =new pcl::OpenNIGrabber (); boost::function<void(constpcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr&)> f = boost::bind (&SimpleOpenNIViewer::cloud_cb_, this, _1);//建立回調函數 // 建立回調函數與回調信號之間綁定 boost::signals2::connection c = interface->registerCallback (f); // 開始接收點雲數據流 interface->start (); while (!viewer.wasStopped ()) { sleep (1); } interface->stop ();
在OpenNIGrabber采集循環執行的回調函數cloud_cb_中,我們首先把獲取到的點雲壓縮到stringstream緩沖區,下一步是解壓縮,它對壓縮了的二進制數據進行解碼,存儲在新的點雲對象中,解碼了的點雲被發送到點雲可視化對象中進行實時可視化。
void cloud_cb_ (const pcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr &cloud) { if (!viewer.wasStopped ()) { std::stringstream compressedData;// 存儲壓縮點雲的字節流對象 pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloudOut // 存儲輸出點雲 (new pcl::PointCloud<pcl::PointXYZRGBA> ()); PointCloudEncoder->encodePointCloud (cloud, compressedData);// 壓縮點雲 PointCloudDecoder->decodePointCloud (compressedData, cloudOut);// 解壓縮點雲 viewer.showCloud (cloudOut);//可視化解壓縮點雲 } } //在壓縮與解壓縮過程中,因為設置compressedData為true所以在標准輸出上打印出壓縮率幀數等信息
編譯並運行該程序
利用光盤提供的CMakeLists.txt文件,在cmake中建立工程文件,並生成相應的可執行文件,生成執行文件后,就可以運行了,在cmd中鍵入命令:
...>point_cloud_compression.exe
可以看到如圖2所示結果,左邊為實時可視化帶RGB紋理信息的點雲結果,用戶縮放可視化結果可以看到經過壓縮后點雲進行了重采樣,紋理信息有所丟失,但數據量有所減小,在實際應用當中需折中取舍。右邊則為實時壓縮信息輸出,可以看出壓縮的幀數、點數、壓縮率等信息。
圖2 點雲壓縮運行結果