基于pcl的点云iss特征点提取

\quad 点云ISS特征提取:
文章:《Intrinsic shape signatures: A shape descriptor for 3D object recognition》
\qquad 内部形状描述子(ISS)是一种表示立体几何形状的方法,该算法含有丰富的几何特征信息。
算法流程:
\qquad 设点云数据有M个点,其任意一点 p i p_i pi坐标为 ( x i , y i , z i ) (x_i,y_i,z_i) (xi,yi,zi), i = 0 , 1 , . . . , M − 1 i=0,1,...,M-1 i=0,1,...,M1
(1)对点云上的每个点 p i p_i pi定义一个局部坐标系,并给定每一个点一个搜索半径 r f r a m e r_{frame} rframe
(2)查询点云数据中每个点 p i p_i pi在半径 r f r a m e r_{frame} rframe周围内的所有点,并计算其权值。 ω i j = 1 / ∣ p i − p j ∣ , ∣ p i − p j ∣ < r frama  \omega_{i j}=1 /\left|p_{i}-p_{j}\right|,\left|p_{i}-p_{j}\right|ωij=1/pipj,pipj<rframa (3)计算每个点 p i p_i pi的协方差矩阵
cov ⁡ ( p i ) = ∑ ∣ p i − p j ∣ < r f  fnux  ω i j ( p i − p j ) ( p i − p j ) T / ∑ ∣ p i − p j ∣ < r franx  ω i j \operatorname{cov}\left(p_{i}\right)=\sum_{\left|p_{i}-p_{j}\right|cov(pi)=pipj<rf fnux ωij(pipj)(pipj)T/pipj<rfranx ωij(4)计算每个点 p i p_i pi的协方差矩阵 c o v ( p i ) cov(p_{i}) cov(pi)的特征值 { λ i 1 , λ i 2 , λ i 3 } \left\{\lambda_{i}^{1}, \lambda_{i}^{2}, \lambda_{i}^{3}\right\} {λi1,λi2,λi3},按从大到顺序排列。
(5)设置阈值 ε 1 \varepsilon_{1} ε1 ε 2 \varepsilon_{2} ε2,满足下式条件的点视为ISS特征点。
λ i 2 / λ i 1 ≤ ε 1 , λ i 3 / λ i 2 ≤ ε 2 \lambda_{ i }^{2} / \lambda_{i}^{1} \leq \varepsilon_{1}, \lambda_{ i }^{3} / \lambda_{i}^{2} \leq \varepsilon_{2} λi2/λi1ε1,λi3/λi2ε2
\quad PCL实现
\qquad 程序:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

void CreateCloudFromTxt(const std::string& file_path,pcl::PointCloud<pcl::PointXYZ>::Ptr cloud)
{
    std::ifstream file(file_path.c_str());
    std::string line;
    std::string no_use;
    pcl::PointXYZ point;
    while (getline(file, line)) {
        string::iterator it;
        for (it = line.begin(); it < line.end(); it++)
        {
          if (*it == ',')
          {
            line.erase(it);
            line.insert(it, ' ');
            it--;
          }
        }
        std::stringstream ss(line);
        ss >> point.x;
        ss >> point.y;
        ss >> point.z;
        cloud->push_back(point);
    }
    file.close();
}

int main(int, char** argv)
   {
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	CreateCloudFromTxt(argv[1],cloud);
	cout << "读取点云个数: " << cloud->points.size() << endl;

	pcl::ISSKeypoint3D<pcl::PointXYZ, pcl::PointXYZ> iss;
	pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints(new pcl::PointCloud<pcl::PointXYZ>());
	pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());

	iss.setInputCloud(cloud);
	iss.setSearchMethod(tree);
	iss.setSalientRadius(0.08f);//设置用于计算协方差矩阵的球邻域半径
	iss.setNonMaxRadius(0.06f);//设置非极大值抑制应用算法的半径
	iss.setThreshold21(0.65); //设定第二个和第一个特征值之比的上限
	iss.setThreshold32(0.5);  //设定第三个和第二个特征值之比的上限
	iss.setMinNeighbors(10); //在应用非极大值抑制算法时,设置必须找到的最小邻居数
	iss.setNumberOfThreads(4); //初始化调度器并设置要使用的线程数
	iss.compute(*keypoints); 

	cout << keypoints->points.size() << endl;

	
	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("ISS"));
	viewer->setBackgroundColor(255,255,255);
	viewer->setWindowName("ISS关键点提取");
	pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> color(cloud, 0.0, 255, 0.0);
	viewer->addPointCloud<pcl::PointXYZ>(cloud, color, "cloud");
	viewer->addPointCloud<pcl::PointXYZ>(keypoints, "keypoint_cloud");//特征点
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "keypoint_cloud");
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 1.0, 0.0, 0.0, "keypoint_cloud");

	while (!viewer->wasStopped())
	{
		viewer->spinOnce(100);
		boost::this_thread::sleep(boost::posix_time::microseconds(100));
	}

	return 0;
}

CMakeLists.txt:

cmake_minimum_required(VERSION 2.8 FATAL_ERROR)

project(iss) 

find_package(PCL REQUIRED)

include_directories(${PCL_INCLUDE_DIRS})

link_directories(${PCL_LIBRARY_DIRS})

add_definitions(${PCL_DEFINITIONS})
 

add_executable (iss iss.cpp) 

target_link_libraries (iss ${PCL_LIBRARIES}) 

实现效果:
基于pcl的点云iss特征点提取_第1张图片

你可能感兴趣的:(机器学习)