1. 程式人生 > >PCL視覺化實現

PCL視覺化實現

    由於各種各樣的問題,CloudViewer類不能正常顯示點雲資料。因此必須使用PCLVisualizer類來實現。下面我根據官方教程的demo寫了一個PCL視覺化的簡單例子。博主也是剛剛開始學習PCL,敬請各位大佬和同學們批評指教!非常樂意和大家一起交流學習。

官方教程:http://www.pclcn.org/study/shownews.php?lang=cn&id=161

    程式碼中的兔子來自於斯坦福大學的網站分享,上面有6個著名3D模型的PLY檔案。PCL可以處理PCD格式和PLY格式,但我還是把模型轉為了PCD格式。

模型來源:https://www.cc.gatech.edu/projects/large_models/

程式碼如下:

#include <iostream>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>

using namespace std;
using namespace pcl;
using namespace io;

int main() {
    PointCloud<PointXYZ>::Ptr cloud(new PointCloud<PointXYZ>);

    if (io::loadPCDFile("bunny.pcd", *cloud) == -1) {
        cerr << "can't read file bunny.pcd" << endl;
        return -1;
    }
    /* 建立視窗物件,並給標題欄定義一個名稱"3D viewer"。viewer的型別為boost::shared_ptr只能共享指標,
     * 這樣做可以保證該指標在整個程式中全域性使用,而不引起記憶體錯誤。
     */
    boost::shared_ptr<visualization::PCLVisualizer> viewer(new visualization::PCLVisualizer("3D viewer"));
    /*設定視窗viewer的背景顏色*/
    viewer->setBackgroundColor(0, 0, 0);
    /*將點雲資料新增到視窗中,併為其定義一個唯一的字串作為ID號,利用此ID號保證其他成員方法也能表示該點雲。
     * 多次呼叫addPointCloud()可以實現多個點雲的疊加,每呼叫一次就建立一個新的ID號。如果想要更新一個已經
     * 顯示的點雲,使用者必須先呼叫removePointCloud(),並提供新的ID號。(在PCL1.1版本之後直接呼叫updatePointCloud()
     * 就可以了,不必手動呼叫removePointCloud()就可實現點雲更新)
     */
    viewer->addPointCloud<PointXYZ>(cloud, "sample cloud");
    /*修改現實點雲的尺寸。使用者可通過該方法控制點雲在視窗中的顯示方式*/
    viewer->setPointCloudRenderingProperties(visualization::PCL_VISUALIZER_POINT_SIZE, 2, "sample cloud");
    /*設定XYZ三個座標軸的大小和長度,該值也可以預設
     *檢視複雜的點雲圖像會讓使用者沒有方向感,為了讓使用者保持正確的方向判斷,需要顯示座標軸。三個座標軸X(R,紅色)
     * Y(G,綠色)Z(B,藍色)分別用三種不同顏色的圓柱體代替。
     */
    viewer->addCoordinateSystem(1.0);
    /*通過設定相機引數是使用者從預設的角度和方向觀察點*/
    viewer->initCameraParameters();

    /*此while迴圈保持視窗一直處於開啟狀態,並且按照規定時間重新整理視窗。
     * wasStopped()判斷顯示視窗是否已經被關閉,spinOnce()叫訊息回撥函式,作用其實是設定更新螢幕的時間
     * this_thread::sleep()在縣城中呼叫sleep()。抱歉,我還不知道這句話的作用
     */
    while (!viewer->wasStopped()) {
        viewer->spinOnce(100);
        boost::this_thread::sleep(boost::posix_time::microseconds(1000));
    }

    return 0;
}

顯示結果: