How to search given 3D point and its index in PCL point cloud data ?

In PCL, backend data structure of point cloud is vector. It is a vector of user defined 3D points. We consider here point cloud data with  point type  pcl::PointXYZ . In the source code we create dummy point cloud data using  rand () function. As original data structure of point cloud is vector, we can use iterators to search specific point in the cloud.
#include <pcl/point_cloud.h>
    #include <pcl/kdtree/kdtree_flann.h>

    #include <iostream>
    #include <vector>
    #include <ctime>
    #include <pcl/console/time.h> //time
    //#include <bits/stdc++.h> 
     pcl::PointXYZ searchPoint1, searchPoint2; 
     int number=1000000; 
    
    int
    main (int argc, char** argv)
    {
      srand (time (NULL));
      pcl::console::TicToc tt;
      pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);

      // Generate pointcloud data
      cloud->width = 10000000;
      cloud->height = 1;
      cloud->points.resize (cloud->width * cloud->height);

      for (std::size_t i = 0; i < cloud->points.size (); ++i)
      {
        cloud->points[i].x = 1024.0f * rand () / (RAND_MAX + 1.0f);
        cloud->points[i].y = 1024.0f * rand () / (RAND_MAX + 1.0f);
        cloud->points[i].z = 1024.0f * rand () / (RAND_MAX + 1.0f);
      }
     /*
       std::cout<< "Points in the point cloud are .." << "\n";
       for (std::size_t i = 0; i < cloud->points.size (); ++i)
      {
       std::cout<< "x= " << cloud->points[i].x << " y= " << cloud->points[i].y 
                << " z= " <<cloud->points[i].z << "\n"; 
      }
     */

      pcl::KdTreeFLANN<pcl::PointXYZ> kdtree;

      kdtree.setInputCloud (cloud);

      //pcl::PointXYZ searchPoint;

      searchPoint1.x = cloud->points[number].x;
      searchPoint1.y = cloud->points[number].y;
      searchPoint1.z = cloud->points[number].z;

      // K nearest neighbor search

      int K = 1;
      //std::vector <int> indices;
      std::vector<int> pointIdxNKNSearch(K);
      std::vector<float> pointNKNSquaredDistance(K);


      std::cout << "K nearest neighbor search at (" << searchPoint1.x 
                << " " << searchPoint1.y 
                << " " << searchPoint1.z
                << ") with K=" << K << std::endl;

      searchPoint1.x= searchPoint1.x+ 0.0001;

      std::cerr << "search kd tree distance...\n", tt.tic (); 

      if (kdtree.nearestKSearch (searchPoint1, K, pointIdxNKNSearch, pointNKNSquaredDistance)> 0)
      {
        for (std::size_t i = 0; i < pointIdxNKNSearch.size (); ++i)
         {
              std::cout << " Searched output index " << pointIdxNKNSearch[0] << "\n";
          }
      }
      std::cerr << ">> Done: " << tt.toc () << " ms, \n";

      // Neighbors within radius search

      std::vector<int> pointIdxRadiusSearch;
      std::vector<float> pointRadiusSquaredDistance;

      //float radius = 256.0f * rand () / (RAND_MAX + 1.0f);
      float radius = 0.001;

      std::cout << "Neighbors within radius search at (" << searchPoint1.x 
                << " " << searchPoint1.y 
                << " " << searchPoint1.z
                << ") with radius=" << radius << std::endl;

      std::cerr << "search kd tree radius...\n", tt.tic (); 

      if ( kdtree.radiusSearch (searchPoint1, radius, 
           pointIdxRadiusSearch, pointRadiusSquaredDistance)> 0 )
      {
            //indices.push_back(pointIdxRadiusSearch[0]);
            std::cout << " Searched output index " << pointIdxRadiusSearch[0] << "\n";
      }

       std::cerr << ">> Done: " << tt.toc () << " ms, \n";

     searchPoint2.x = cloud->points[number].x;
     searchPoint2.y = cloud->points[number].y;
     searchPoint2.z = cloud->points[number].z;

    std::cout << " Searching with stl vector method with custom comparator.. " << "\n", tt.tic ();
    //std::vector<pcl::PointXYZ>::iterator auto used instead 
    auto it2 = std::find_if(cloud->begin(), cloud->end(), [](const pcl::PointXYZ & p){
             if (p.x== searchPoint2.x && p.y== searchPoint2.y && p.z== searchPoint2.z)
                                        return true;
                                                      });

    if (it2 != cloud->end())
      std::cout << "Output index using STL search : " << distance(cloud->begin(), it2) << std::endl;
    else
        std::cout << "Point Not Found" << std::endl;
     std::cerr << ">> Done: " << tt.toc () << " ms, \n";

    return 0;
    }


CMakeLists.txt

# CMake instructions to make the static lib
cmake_minimum_required(VERSION 3.2)
project(kdtree_search)
set (CMAKE_CXX_STANDARD 11)

#PCL library 
find_package(PCL 1.8 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})

# Replace SHARED by STATIC for static library, 
ADD_EXECUTABLE( kdtree_search kdtree_search.cpp) 

TARGET_LINK_LIBRARIES(kdtree_search ${PCL_LIBRARIES})


Demo:



That's all now for the scope post. 

No comments:

Post a Comment

Rendering 3D maps on the web using opesource javascript library Cesium

This is a simple 3D viewer using the Cesium javascript library. The example code can be found here . Click on question-mark symbol on upp...