Developer Guide

  • 2022.3
  • 10/25/2022
  • Public Content
Contents

Intel® oneAPI Base Toolkit's Iterative Closest Point (ICP)

ICP is an algorithm employed to minimize the difference between two clouds of points. The standard, not joint nor generalized, ICP has been optimized using the Intel® oneAPI Base Toolkit.
See registration_api for details.
This tutorial shows how to use these optimizations inside a Docker* image. For the same functionality outside of Docker* images, see PCL Optimizations Outside of Docker* Images.
  1. Prepare the environment:
    cd <edge_insights_for_amr_path>/Edge_Insights_for_Autonomous_Mobile_Robots_<version>/AMR_containers ./run_interactive_docker.sh eiforamr-full-flavour-sdk:2022.3 root -c full_flavor mkdir one_api_registration && cd one_api_registration
  2. Create the file
    oneapi_icp_example.cpp
    :
    vim oneapi_icp_example.cpp
  3. Place the following inside the file:
    #include <pcl/oneapi/registration/icp.h> #include <pcl/console/parse.h> #include <pcl/point_types.h> #include <pcl/point_cloud.h> #include <pcl/point_representation.h> #include <pcl/io/pcd_io.h> using namespace pcl; using namespace pcl::io; using namespace pcl::console; /* ---[ */ int main (int argc, char** argv) { // Parse the command line arguments for .pcd files std::vector<int> p_file_indices; p_file_indices = parse_file_extension_argument (argc, argv, ".pcd"); if (p_file_indices.size () != 2) { print_error ("Need one input source PCD file and one input target PCD file to continue.\n"); print_error ("Example: %s source.pcd target.pcd\n", argv[0]); return (-1); } // Load the files print_info ("Loading %s as source and %s as target...\n", argv[p_file_indices[0]], argv[p_file_indices[1]]); PointCloud<PointXYZ>::Ptr src, tgt; src.reset (new PointCloud<PointXYZ>); tgt.reset (new PointCloud<PointXYZ>); if (loadPCDFile (argv[p_file_indices[0]], *src) == -1 || loadPCDFile (argv[p_file_indices[1]], *tgt) == -1) { print_error ("Error reading the input files!\n"); return (-1); } PointCloud<PointXYZ> output; // Compute the best transformtion pcl::oneapi::IterativeClosestPoint<PointXYZ, PointXYZ> reg; reg.setMaximumIterations(20); reg.setTransformationEpsilon(1e-12); reg.setMaxCorrespondenceDistance(2); reg.setInputSource(src); reg.setInputTarget(tgt); // Register reg.align(output); //point cloud output of alignment i.e source cloud after transformation is applied. Eigen::Matrix4f transform = reg.getFinalTransformation(); std::cerr << "Transform Matrix:" << std::endl; std::cerr << transform << std::endl; // Write transformed data to disk savePCDFileBinary ("source_transformed.pcd", output); } /* ]--- */
  4. Create a CMakeLists.txt file:
    vim CMakeLists.txt
  5. Place the following inside the file:
    cmake_minimum_required(VERSION 3.5 FATAL_ERROR) set(target oneapi_icp_example) set(CMAKE_CXX_COMPILER dpcpp) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_FLAGS "-Wall -Wpedantic -Wno-unknown-pragmas -Wno-pass-failed -Wno-unneeded-internal-declaration -Wno-unused-function -Wno-gnu-anonymous-struct -Wno-nested-anon-types -Wno-extra-semi -Wno-unused-local-typedef -fsycl -fsycl-unnamed-lambda -ferror-limit=1") project(registration) find_package(PCL 1.12 REQUIRED) find_package(PCL-ONEAPI 1.12 REQUIRED) add_executable (${target} oneapi_icp_example.cpp) include_directories(${PCL_INCLUDE_DIRS} ${PCL-ONEAPI_INCLUDE_DIRS}) link_directories(${PCL_LIBRARY_DIRS} ${PCL-ONEAPI_LIBRARY_DIRS}) add_definitions(${PCL_DEFINITIONS} ${PCL-ONEAPI_DEFINITIONS}) target_link_libraries (${target} sycl pcl_oneapi_registration pcl_oneapi_search pcl_oneapi_kdtree pcl_io)
  6. Source the Intel® oneAPI Base Toolkit environment:
    export PATH=/home/eiforamr/workspace/lib/pcl/share/pcl-1.12:/home/eiforamr/workspace/lib/pcl/share/pcl-oneapi-1.12:$PATH source /opt/intel/oneapi/setvars.sh
  7. Build the code:
    cd /home/eiforamr/workspace/one_api_registration/ mkdir build && cd build cmake ../ make -j
  8. Download the test data from GitHub*:
    wget https://raw.githubusercontent.com/NVIDIA-AI-IOT/cuPCL/main/cuOctree/test_P.pcd wget https://raw.githubusercontent.com/NVIDIA-AI-IOT/cuPCL/main/cuOctree/test_Q.pcd # if the binaries is not downloaded try setting the proxies first and try again: export http_proxy="http://<http_proxy>:port" export https_proxy="http://<https_proxy>:port"
  9. Run the binary:
    ./oneapi_icp_example test_P.pcd test_Q.pcd
Expected results example:
Transform Matrix: 0.998899 0.0107221 0.0457259 0.0790768 -0.00950837 0.999602 -0.0266773 0.0252976 -0.0459936 0.026213 0.998599 0.0677631 0 0 0 1

Code Explanation

Define two input point Clouds (src, tgt), declare the output point cloud, and load the test data from GitHub*.
PointCloud<PointXYZ>::Ptr src, tgt; src.reset (new PointCloud<PointXYZ>); tgt.reset (new PointCloud<PointXYZ>); if (loadPCDFile (argv[p_file_indices[0]], *src) == -1 || loadPCDFile (argv[p_file_indices[1]], *tgt) == -1) { print_error ("Error reading the input files!\n"); return (-1); } PointCloud<PointXYZ> output;
Declare the Intel® oneAPI Base Toolkit's ICP, and set the input configuration parameters.
pcl::oneapi::IterativeClosestPoint<PointXYZ, PointXYZ> reg; reg.setMaximumIterations(20); reg.setTransformationEpsilon(1e-12); reg.setMaxCorrespondenceDistance(2);
Set the two input point clouds for the ICP module, and call the method to align the two point clouds. The align method populates the output point cloud, passed as a parameter, with the src point cloud transformed using the computed transformation matrix.
reg.setInputSource(src); reg.setInputTarget(tgt); // Register reg.align(output); //point cloud output of alignment i.e source cloud after transformation is applied.
Get the computed matrix transformation, print it, and save the transformed point cloud.
Eigen::Matrix4f transform = reg.getFinalTransformation(); std::cerr << "Transform Matrix:" << std::endl; std::cerr << transform << std::endl; // Write transformed data to disk savePCDFileBinary ("source_transformed.pcd", output);

Product and Performance Information

1

Performance varies by use, configuration and other factors. Learn more at www.Intel.com/PerformanceIndex.