天天看點

pcl 無序點雲資料空間變化檢測原理CodeResult

pcl 無序點雲資料空間變化檢測

  • 原理
  • Code
  • Result

原理

octree是一種管理稀疏3D資料的樹狀結構,利用octree實作多個無序點雲之間的空間變化檢測,這些點雲可能在尺寸。分辨率 密度,和點順序等方面有所差異,通過遞歸的比較octree的樹結構,可以鑒定出由octree産生的體素組成的差別所代表的空間變化,并且通過octree的“雙緩沖”技術,可以實時的探測多個點雲之間的空間組成的差異。

對無序點雲在空間變化上的檢測,其實是對前後兩幅點雲在八叉樹結構下的差異檢測。是以我們要首先載入一個原始點雲,并生成第一個八叉樹結構;然後切緩沖,載入第二個點雲,生成第二個八叉樹結構;最後進行比較,如果有一些葉子結點在第二個八叉樹上,但是不在第一個八叉樹上,那麼就認為這些葉子節點内的點是空間上變化多出來的點。

Code

=====================================================

#include <pcl/point_cloud.h>
#include <pcl/octree/octree.h>
#include <iostream>
#include <vector>
#include <ctime>
           

包含的頭檔案

=====================================================

//建立時間随機種子  取随機數用的
    srand ((unsigned int) time (NULL));

    //聲明一個點雲 A  指針 并配置設定空間
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloudA (new pcl::PointCloud<pcl::PointXYZ> );
    
    //定義點雲大小  點雲個數128個,無序
    cloudA->width =128;
    cloudA->height =1;
    cloudA->points.resize (cloudA->width *cloudA->height);
    //循環給點雲指派 通過 随機數  點雲的坐标 0-64
    for (size_t i=0; i<cloudA->points.size (); ++i)
    {
        cloudA->points[i].x =64.0f* rand () / (RAND_MAX +1.0f);
        cloudA->points[i].y =64.0f* rand () / (RAND_MAX +1.0f);
        cloudA->points[i].z =64.0f* rand () / (RAND_MAX +1.0f);
    }
           

建立一個點雲 cloudA

個數 128個 x,y,z的坐标 0-64 取随機值

=====================================================

/* 設定分辨率 描述的是最低一級 八叉樹 的 最小體素 的 尺寸*/
    float resolution =32.0f;
    
    /* 建構 八叉樹 變化 檢測 的 類 并設定 分辨率 */
    pcl::octree::OctreePointCloudChangeDetector<pcl::PointXYZ>octree (resolution);  

           

建構 八叉樹 變化 檢測 的 類 并設定 分辨率

=====================================================

/* 指派八叉樹的 點雲 */
    octree.setInputCloud (cloudA);//設定輸入的點雲
    octree.addPointsFromInputCloud ();//将輸入的點雲添加到八叉樹

           

将 cloudA 輸入 八叉樹 ,建構其資料結構 将其作為基礎點雲

後面可檢測比其多的點雲多的點。但是不能檢測 第二個點雲比其少的點

=====================================================

/*交換八叉樹緩存,但是cloudA對應的八叉樹仍在記憶體中*/ 
    octree.switchBuffers ();
           

點雲 cloudA 是 參考點雲 ,用其建立的八叉樹對象 描述它的空間分布

OctreePointCloudChangeDetector繼承自 Octree2BufBase 類,該類允許同時在記憶體中儲存和管理兩個八叉樹

它應用了記憶體池,重複利用已經配置設定的節點對象,減少記憶體配置設定和釋放操作

通過通路octree.switchBuffers () 重置了八叉樹對象的緩存區,但把之前的八叉樹仍然留着緩存中

=====================================================

//聲明一個點雲 B  指針 并配置設定空間
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloudB (new pcl::PointCloud<pcl::PointXYZ> );
    
    //定義點雲大小  點雲個數128個,無序
    cloudB->width =128;
    cloudB->height =1;
    cloudB->points.resize (cloudB->width *cloudB->height);
    //循環給點雲指派 通過 随機數  點雲的坐标 0-64
    for (size_t i=0; i<cloudB->points.size (); ++i)
    {
        cloudB->points[i].x =90.0f* rand () / (RAND_MAX +1.0f);
        cloudB->points[i].y =90.0f* rand () / (RAND_MAX +1.0f);
        cloudB->points[i].z =90.0f* rand () / (RAND_MAX +1.0f);
    }
           

聲明一個點雲 B 指針 并配置設定空間

個數 128個 x,y,z的坐标 0-90 取随機值

範圍比A 大一點 ,容易有效果

=====================================================

/*聲明 B 比 A 多 出 的點雲 的索引值 儲存 向量*/
    std::vector<int>newPointIdxVector;

    /* 得到B比A 多出來的 索引值  注意 B 比 A  少的  不會得到  */
    octree.getPointIndicesFromNewVoxels (newPointIdxVector);
           

通過 函數 getPointIndicesFromNewVoxels 得 到 B比A 多出來的 索引值

=====================================================

// 終端列印 B 比 A 多出 來的  點雲
    std::cout<<"Output from getPointIndicesFromNewVoxels:"<<std::endl;
    for (size_t i=0; i<newPointIdxVector.size (); ++i)
    std::cout<<i<<"# Index:"<<newPointIdxVector[i]
    <<"  Point:"<<cloudB->points[newPointIdxVector[i]].x <<" "
    <<cloudB->points[newPointIdxVector[i]].y <<" "
    <<cloudB->points[newPointIdxVector[i]].z <<std::endl;

           

終端列印 B 比 A 多出 來的 點雲

=====================================================

//聲明一個點雲 C  指針 并配置設定空間
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloudC (new pcl::PointCloud<pcl::PointXYZ> );
    //定義點雲大小  點雲個數上面計算的 B 比 A 多出的 個,無序
    cloudC->width =newPointIdxVector.size ();
    cloudC->height =1;
    cloudC->points.resize (cloudC->width *cloudC->height);

    for(size_t i=0;i<newPointIdxVector.size ();++i)
    {
        cloudC->points[i]=cloudB->points[newPointIdxVector[i]];

    }

           

建立一個點雲C 來儲存 B比A 多出來的點

=====================================================

//可視化子產品
    pcl::visualization::PCLVisualizer::Ptr viewer (new pcl::visualization::PCLVisualizer ("3D Viewwe"));//建立指針viewer
    viewer->initCameraParameters();//初始化相機參數
           

添加可視子產品 來 把 點雲顯示出來

=====================================================

int v1(0);//第一個視窗的參數
    viewer->createViewPort(0.0,0.0,0.33,1,v1); //設定第一個視窗的大小,位于螢幕左側
    viewer->setBackgroundColor(0,0,0,v1);//background of first port
    viewer->addText("cloudA",10,10,"cloudA",v1);//好像是一個便簽
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color1(cloudA,255,0,0);//設定第一個點雲的顔色
    viewer->addPointCloud<pcl::PointXYZ>(cloudA,single_color1,"cloudA",v1);//顯示第一個點雲
           

把 點雲A 顯示為 紅色

=====================================================

int v2(0);//第一個視窗的參數
    viewer->createViewPort(0.33,0,0.66,1,v2);//設定第二個視窗的大小,位于螢幕右側
    viewer->setBackgroundColor(0,0,0,v2);//background of second port
    viewer->addText("cloudB",10,9,"cloudB",v2);//輸出一行文字
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color2(cloudB,0,255,0);//設定第二個點雲的顔色
    viewer->addPointCloud<pcl::PointXYZ>(cloudB,single_color2,"simple_cloud2",v2);//顯示第二個點雲
           

第二個視窗 點雲 B 顯示 為綠色

=====================================================

//第三個點雲視窗
    int v3(0);//第三個視窗的參數
    viewer->createViewPort(0.66,0,1,1,v3);//視窗大小
    viewer->setBackgroundColor(0,0,0,v3);//背景顔色
    viewer->addText("cloud_result",10,8,"cloud_result",v3);//好像是一個便簽
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color3(cloudC,255,255,255);//點雲顔色

    viewer->addPointCloud<pcl::PointXYZ>(cloudA,single_color1,"cloud1",v3);//顯示點雲
    viewer->addPointCloud<pcl::PointXYZ>(cloudB,single_color2,"cloud2",v3);//顯示點雲
    viewer->addPointCloud<pcl::PointXYZ>(cloudC,single_color3,"cloud3",v3);//顯示點雲
    viewer->addCoordinateSystem(2);//添加坐标系
    viewer->spin();
           

第三個視窗将 點雲A、B、C 顯示在一起。來看下整體效果

=====================================================

Result

pcl 無序點雲資料空間變化檢測原理CodeResult

終端列印的 B 比A 多出的 點雲

pcl 無序點雲資料空間變化檢測原理CodeResult

點雲顯示的點

左邊為點雲A ,中間為點雲B

右邊為三個點雲的組合;

紅色的是A點雲有B點雲沒有的;綠色為A和B共有的;白色為B比A 多的。

繼續閱讀