Plane Model Segmentation#

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:2023.1 root -c full_flavor
    mkdir one_api_segmentation && cd one_api_segmentation
    
  2. Create the file oneapi_segmentation.cpp:

    vim oneapi_segmentation.cpp
    
  3. Place the following inside the file:

    #include <pcl/oneapi/segmentation/segmentation.h>
    #include <pcl/io/pcd_io.h>
    #include <pcl/point_types.h>
    #include <pcl/pcl_config.h>
    
    int main (int argc, char **argv)
    {
        //Read Point Cloud
        pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_input (new pcl::PointCloud<pcl::PointXYZ> ());
    
        //Load a standard PCD file from disk
        int result = pcl::io::loadPCDFile(argv[1], *cloud_input);
        if (result != 0)
        {
            pcl::console::print_info ("Load pcd file failed.\n");
            return result;
        }
    
        //Create the oneapi_segmentation object
        pcl::oneapi::SACSegmentation seg;
    
        //Configure oneapi_segmentation class 
        seg.setInputCloud(cloud_input);
        seg.setProbability(0.99);
        seg.setMaxIterations(50);
        seg.setDistanceThreshold(0.01);
        //Optional  
        seg.setOptimizeCoefficients(true);
        //Set algorithm method and model type 
        seg.setMethodType(pcl::oneapi::SAC_RANSAC);
        seg.setModelType (pcl::oneapi::SACMODEL_PLANE);
    
        //Out parameter declaration for getting inliers and model coefficients  
        pcl::PointIndices::Ptr inliers (new pcl::PointIndices);
        double coeffs[4]={0,0,0,0};
        
        //Getting inliers and model coefficients
        seg.segment(*inliers, coeffs);
    
        std::cout << "input cloud size   : " << seg.getCloudSize() << std::endl;
        std::cout << "inliers size       : " << seg.getInliersSize() << std::endl;
        std::cout << "model coefficients : " << coeffs[0] << ", " << coeffs[1] << ", " << coeffs[2] << ", " << coeffs[3] << std::endl;
    
        return 0;
    }
    
  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_segmentation)
    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(${target})
    
    find_package(PCL 1.12 REQUIRED)
    find_package(PCL-ONEAPI 1.12 REQUIRED)
    
    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})
    
    add_executable (${target} oneapi_segmentation.cpp)
    target_link_libraries (${target} sycl pcl_oneapi_containers pcl_oneapi_segmentation ${PCL_LIBRARIES})
    
  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_segmentation/
    mkdir build && cd build
    cmake ../
    make -j
    
  8. Download the test data from GitHub*:

    wget https://raw.githubusercontent.com/PointCloudLibrary/data/5c26bdd0591ba150b91858b5c9fe5e91cb39ae86/segmentation/mOSD/test/test59.pcd
    # if the binary 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_segmentation ./test59.pcd
    

Expected results example:

input cloud size   : 307200
inliers size       : 25332
model coefficients : -0.176599, -1.87228, -1.08408, 1

Code Explanation#

Load the test data from GitHub* into a PointCloud<PointXYZ>.

    //Read Point Cloud
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_input (new pcl::PointCloud<pcl::PointXYZ> ());

Create the oneapi_segmentation object.

    pcl::oneapi::SACSegmentation seg;

Configure the oneapi_segmentation class.

    seg.setInputCloud(cloud_input);
    seg.setProbability(0.99);
    seg.setMaxIterations(50);
    seg.setDistanceThreshold(0.01);
    //Optional  
    seg.setOptimizeCoefficients(true);
    //Set algorithm method and model type 
    seg.setMethodType(pcl::oneapi::SAC_RANSAC);
    seg.setModelType (pcl::oneapi::SACMODEL_PLANE);

Set to true if a coefficient refinement is required.

    seg.setOptimizeCoefficients(true);

Set the algorithm method and model type.

    seg.setMethodType(pcl::oneapi::SAC_RANSAC);
    seg.setModelType (pcl::oneapi::SACMODEL_PLANE);

Declare output parameters for getting inliers and model coefficients.

    pcl::PointIndices::Ptr inliers (new pcl::PointIndices);
    double coeffs[4]={0,0,0,0};

Get inliers and model coefficients by calling the segment() API.

    seg.segment(*inliers, coeffs);

Result (output log):

    std::cout << "input cloud size   : " << seg.getCloudSize() << std::endl;
    std::cout << "inliers size       : " << seg.getInliersSize() << std::endl;
    std::cout << "model coefficients : " << coeffs[0] << ", " << coeffs[1] << ", " << coeffs[2] << ", " << coeffs[3] << std::endl;