\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,...,M−1
(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|<r_{\text {frama }}
ωij=1/∣pi−pj∣,∣pi−pj∣<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|<r_{f \text { fnux }}} \omega_{i j}\left(p_{i}-p_{j}\right)\left(p_{i}-p_{j}\right)^{T} / \sum_{\left|p_{i}-p_{j}\right|<r_{\text {franx }}} \omega_{i j}
cov(pi)=∣pi−pj∣<rf fnux ∑ωij(pi−pj)(pi−pj)T/∣pi−pj∣<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 <iostream>
#include <pcl/point_types.h>
#include <pcl/common/io.h>
#include <pcl/keypoints/iss_3d.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>
#include <pcl/kdtree/impl/kdtree_flann.hpp>
#include <pcl/search/impl/search.hpp>
#include <pcl/impl/instantiate.hpp>
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})
实现效果: