Search-Octree-PCL-Cpp (70%)

PCL-CPP ๊ธฐ๋ฐ˜ Octree ํƒ์ƒ‰

์ฝ”๋“œ๋Š” [์ด๊ณณ]์—์„œ ๋‹ค์šด๋กœ๋“œ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ƒ˜ํ”ŒํŒŒ์ผ์€ [cloud_cluster_0.pcd]์„ ์‚ฌ์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค.

#include <pcl/io/pcd_io.h> 
#include <pcl/octree/octree_search.h>  
#include <pcl/visualization/cloud_viewer.h>  
#include <pcl/point_types.h>  

#include <iostream>
#include <vector>

//Spatial Partitioning and Search Operations with Octrees
//http://pointclouds.org/documentation/tutorials/octree.php#octree-search
//Commnets : Hunjung, Lim (hunjung.lim@hotmail.com)

int main()
{

    pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);

     // *.PCD ํŒŒ์ผ ์ฝ๊ธฐ (https://raw.githubusercontent.com/adioshun/gitBook_Tutorial_PCL/master/Intermediate/sample/cloud_cluster_0.pcd)
    pcl::io::loadPCDFile<pcl::PointXYZRGB>("cloud_cluster_0.pcd", *cloud);

     // ์‹œ๊ฐ์  ํ™•์ธ์„ ์œ„ํ•ด ์ƒ‰์ƒ ํ†ต์ผ (255,255,255)
    for (size_t i = 0; i < cloud->points.size(); ++i){
        cloud->points[i].r = 255;
        cloud->points[i].g = 255;
        cloud->points[i].b = 255;
    }

    //Octree ์˜ค๋ธŒ์ ํŠธ ์ƒ์„ฑ 
    float resolution = 0.03f; //๋ณต์…€ ํฌ๊ธฐ ์„ค์ •(Set octree voxel resolution)
    pcl::octree::OctreePointCloudSearch<pcl::PointXYZRGB> octree(resolution); 
    octree.setInputCloud(cloud);       // ์ž…๋ ฅ 
    octree.addPointsFromInputCloud();  //Octree ์ƒ์„ฑ (Build Octree)

    //๊ธฐ์ค€์ (searchPoint) ์„ค์ • ๋ฐฉ๋ฒ• #1(x,y,z ์ขŒํ‘œ ์ง€์ •)
    //pcl::PointXYZRGB searchPoint;
    //searchPoint.x = 0.026256f;
      //searchPoint.y = -1.464739f;
      //searchPoint.z = 0.929567f;

    //๊ธฐ์ค€์ (searchPoint) ์„ค์ • ๋ฐฉ๋ฒ• #2(3000๋ฒˆ์งธ ํฌ์ธํŠธ)
    pcl::PointXYZRGB searchPoint = cloud->points[3000]; 

     //๊ธฐ์ค€์  ์ขŒํ‘œ ์ถœ๋ ฅ 
     std::cout << "searchPoint :" << searchPoint.x << " " << searchPoint.y << " " << searchPoint.z  << std::endl;

     //๊ธฐ์ค€์ ๊ณผ ๋™์ผํ•œ ๋ณต์…€๋‚ด ์กด์žฌ ํ•˜๋Š” ํ•˜๋Š” ํฌ์ธํŠธ ํƒ์ƒ‰(Voxel Neighbor Search)
    std::vector<int> pointIdxVec;  //๊ฒฐ๊ณผ๋ฌผ ํฌ์ธํŠธ์˜ Index ์ €์žฅ(Save the result vector of the voxel neighbor search) 

    if (octree.voxelSearch(searchPoint, pointIdxVec))
    {
        //์‹œ๊ฐ์  ํ™•์ธ์„ ์œ„ํ•˜์—ฌ ์ƒ‰์ƒ ๋ณ€๊ฒฝ (255,0,0)
        for (size_t i = 0; i < pointIdxVec.size(); ++i){
            cloud->points[pointIdxVec[i]].r = 255;
            cloud->points[pointIdxVec[i]].g = 0;
            cloud->points[pointIdxVec[i]].b = 0;
        }        
    }

    // ๊ธฐ์ค€์ ์—์„œ ๊ฐ€๊นŒ์šด ์ˆœ์„œ์ค‘ K๋ฒˆ์งธ๊นŒ์ง€์˜ ํฌ์ธํŠธ ํƒ์ƒ‰ (K nearest neighbor search)
    int K = 50;   // ํƒ์ƒ‰ํ•  ํฌ์ธํŠธ ์ˆ˜ ์„ค์ • 
    std::vector<int> pointIdxNKNSearch; //Save the index result of the K nearest neighbor
    std::vector<float> pointNKNSquaredDistance;  //Save the index result of the K nearest neighbor

    if (octree.nearestKSearch(searchPoint, K, pointIdxNKNSearch, pointNKNSquaredDistance) > 0)
    {   
          //์‹œ๊ฐ์  ํ™•์ธ์„ ์œ„ํ•˜์—ฌ ์ƒ‰์ƒ ๋ณ€๊ฒฝ (0,255,0)
        for (size_t i = 0; i < pointIdxNKNSearch.size(); ++i){
            cloud->points[pointIdxNKNSearch[i]].r = 0;
            cloud->points[pointIdxNKNSearch[i]].g = 255;
            cloud->points[pointIdxNKNSearch[i]].b = 0;
        }    
    }

     // ํƒ์ƒ‰๋œ ์ ์˜ ์ˆ˜ ์ถœ๋ ฅ 
    std::cout << "K = 50 nearest neighbors:" << pointIdxNKNSearch.size() << endl;

    //๊ธฐ์ค€์ ์—์„œ ์ง€์ •๋œ ๋ฐ˜๊ฒฝ๋‚ด ํฌ์ธํŠธ ํƒ์ƒ‰ (Neighbor search within radius)
    float radius = 0.02; //ํƒ์ƒ‰ํ•  ๋ฐ˜๊ฒฝ ์„ค์ •(Set the search radius)
     std::vector<int> pointIdxRadiusSearch;  //Save the index of each neighbor
    std::vector<float> pointRadiusSquaredDistance;  //Save the square of the Euclidean distance between each neighbor and the search point

    if (octree.radiusSearch(searchPoint, radius, pointIdxRadiusSearch, pointRadiusSquaredDistance) > 0)
    {    
          //์‹œ๊ฐ์  ํ™•์ธ์„ ์œ„ํ•˜์—ฌ ์ƒ‰์ƒ ๋ณ€๊ฒฝ (0,0,255)
        for (size_t i = 0; i < pointIdxRadiusSearch.size(); ++i){
            cloud->points[pointIdxRadiusSearch[i]].r = 0;
            cloud->points[pointIdxRadiusSearch[i]].g = 0;
            cloud->points[pointIdxRadiusSearch[i]].b = 255;
        }        
    }

     // ํƒ์ƒ‰๋œ ์ ์˜ ์ˆ˜ ์ถœ๋ ฅ 
    std::cout << "Radius 0.02 nearest neighbors: " << pointIdxRadiusSearch.size() << endl;

     // ์ƒ์„ฑ๋œ ํฌ์ธํŠธํด๋ผ์šฐ๋“œ ์ €์žฅ 
    pcl::io::savePCDFile<pcl::PointXYZRGB>("Octree_AllinOne.pcd", *cloud);
}

๊ฒฐ๊ณผ

์ฐธ๊ณ ์œ„์น˜

๊ฒฐ๊ณผ

๊ฐ ๊ธฐ๋Šฅ๋ณ„ ์ฝ”๋“œ 3๊ฐœ

์ฝ”๋“œ๋Š” [์ด๊ณณ]์—์„œ ๋‹ค์šด๋กœ๋“œ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ƒ˜ํ”ŒํŒŒ์ผ์€ [cloud_cluster_0.pcd]์„ ์‚ฌ์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ

์ฝ”๋“œ๋Š” [์ด๊ณณ]์—์„œ ๋‹ค์šด๋กœ๋“œ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ƒ˜ํ”ŒํŒŒ์ผ์€ [cloud_cluster_0.pcd]์„ ์‚ฌ์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ

์ฝ”๋“œ๋Š” [์ด๊ณณ]์—์„œ ๋‹ค์šด๋กœ๋“œ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ƒ˜ํ”ŒํŒŒ์ผ์€ [cloud_cluster_0.pcd]์„ ์‚ฌ์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ

Last updated

Was this helpful?