Using SampleConsensusInitialAligment (SCIA) to Initial Align Two Point Clouds#
In this tutorial, we will learn how to initial align two point clouds, using SCIA, provided with the transformation 4x4 matrix.
Note
This tutorial is applicable for execution for both within inside and outside a Docker image. It assumes that the pcl-oneapi-tutorials Deb package is installed, and the user has copied the tutorial directory from /opt/intel/pcl/oneapi/tutorials/ to a user-writable directory.
Prepare the environment:
cd <path-to-oneapi-tutorials>/sample_consensus_initial_alignment
oneapi_scia.cpp
should be in the directory with following content:1// SPDX-License-Identifier: Apache-2.0 2// Copyright (C) 2025 Intel Corporation 3#include <pcl/oneapi/registration/ia_ransac.h> 4#include <pcl/io/pcd_io.h> 5#include <pcl/point_types.h> 6#include <pcl/point_cloud.h> 7 8 9using namespace pcl; 10using namespace pcl::io; 11 12int main (int argc, char** argv) 13{ 14 std::cout << "Running on device: " << dpct::get_default_queue().get_device().get_info<sycl::info::device::name>() << "\n"; 15 16 // Read Point Cloud 17 PointCloud<PointXYZ> cloud_source, cloud_target; 18 PointCloud<FPFHSignature33> FPFH_cloud_source, FPFH_cloud_target; 19 20 if (loadPCDFile<PointXYZ>("../../data/scia_source.pcd", cloud_source) < 0) 21 { 22 std::cerr << "Failed to read alignment source point cloud, please check scia_source.pcd" << std::endl; 23 return (-1); 24 } 25 if (loadPCDFile<PointXYZ>("../../data/scia_target.pcd", cloud_target) < 0) 26 { 27 std::cerr << "Failed to read alignment target point cloud, please check scia_target.pcd" << std::endl; 28 return (-1); 29 } 30 if (loadPCDFile<FPFHSignature33>("../../data/scia_source_fpfh33.pcd", FPFH_cloud_source) < 0) 31 { 32 std::cerr << "Failed to read FPFH feature cloud of alignment source point cloud, please check scia_source_fpfh33.pcd" << std::endl; 33 return (-1); 34 } 35 if (loadPCDFile<FPFHSignature33>("../../data/scia_target_fpfh33.pcd", FPFH_cloud_target) < 0) 36 { 37 std::cerr << "Failed to read FPFH feature cloud of alignment target point cloud, please check scia_target_fpfh33.pcd" << std::endl; 38 return (-1); 39 } 40 41 // GPU calculate 42 pcl::oneapi::SampleConsensusInitialAlignment<PointXYZ, PointXYZ, FPFHSignature33> scia; 43 scia.setInputSource(cloud_source.makeShared()); 44 scia.setInputTarget(cloud_target.makeShared()); 45 scia.setSourceFeatures(FPFH_cloud_source.makeShared()); 46 scia.setTargetFeatures(FPFH_cloud_target.makeShared()); 47 48 constexpr float SACdismin = 0.02f; 49 constexpr int SCANum = 20; 50 constexpr int SCAradomn = 100; 51 scia.setMinSampleDistance(SACdismin); 52 scia.setNumberOfSamples(SCANum); 53 scia.setCorrespondenceRandomness(SCAradomn); 54 55 PointCloud<PointXYZ> cloud_result; 56 Eigen::Matrix4f sac_trans; 57 scia.align(cloud_result); 58 sac_trans = scia.getFinalTransformation(); 59 60 // print log 61 std::cout << "[oneapi SCIA] Transformation Matrix 4x4 = " << std::endl << sac_trans << std::endl; 62}
Source the Intel® oneAPI Base Toolkit environment:
source /opt/intel/oneapi/setvars.sh
Build the code:
mkdir build && cd build cmake ../ make -j
Run the binary:
./oneapi_scia
Expected results example:
[oneapi SCIA] Transformation Matrix 4x4 = 0.268113 -0.734448 -0.623458 0.289958 0.748389 -0.248733 0.614853 -0.208532 -0.606653 -0.63144 0.482965 0.229585 0 0 0 1
Code Explanation#
Load source/target/fpfh_source/fpfh_target
PCD file
if (loadPCDFile<PointXYZ>("../../data/scia_source.pcd", cloud_source) < 0)
{
std::cerr << "Failed to read alignment source point cloud, please check scia_source.pcd" << std::endl;
return (-1);
}
if (loadPCDFile<PointXYZ>("../../data/scia_target.pcd", cloud_target) < 0)
{
std::cerr << "Failed to read alignment target point cloud, please check scia_target.pcd" << std::endl;
return (-1);
}
Load the example source/target/fpfh_source/fpfh_target
PCD into a PointCloud<PointXYZ/FPFHSignature33>
.
if (loadPCDFile<FPFHSignature33>("../../data/scia_source_fpfh33.pcd", FPFH_cloud_source) < 0)
{
std::cerr << "Failed to read FPFH feature cloud of alignment source point cloud, please check scia_source_fpfh33.pcd" << std::endl;
return (-1);
}
if (loadPCDFile<FPFHSignature33>("../../data/scia_target_fpfh33.pcd", FPFH_cloud_target) < 0)
{
std::cerr << "Failed to read FPFH feature cloud of alignment target point cloud, please check scia_target_fpfh33.pcd" << std::endl;
return (-1);
}
Start to compute the model.
// GPU calculate
pcl::oneapi::SampleConsensusInitialAlignment<PointXYZ, PointXYZ, FPFHSignature33> scia;
scia.setInputSource(cloud_source.makeShared());
scia.setInputTarget(cloud_target.makeShared());
scia.setSourceFeatures(FPFH_cloud_source.makeShared());
scia.setTargetFeatures(FPFH_cloud_target.makeShared());
constexpr float SACdismin = 0.02f;
constexpr int SCANum = 20;
constexpr int SCAradomn = 100;
scia.setMinSampleDistance(SACdismin);
scia.setNumberOfSamples(SCANum);
scia.setCorrespondenceRandomness(SCAradomn);
PointCloud<PointXYZ> cloud_result;
Eigen::Matrix4f sac_trans;
scia.align(cloud_result);
sac_trans = scia.getFinalTransformation();
Result (output log).
// print log
std::cout << "[oneapi SCIA] Transformation Matrix 4x4 = " << std::endl << sac_trans << std::endl;