泛化的ICP算法,通过协方差矩阵起到类似于权重的作用,消除某些不好的对应点在求解过程中的作用。不过可以囊括Point to Point,Point to Plane的ICP算法,真正的是泛化的ICP。牛!

CC中的GICP插件

void qLxPluginPCL::doSpraseRegistration()
{
assert(m_app);
if (!m_app)
return; const ccHObject::Container& selectedEntities = m_app->getSelectedEntities();
size_t selNum = selectedEntities.size();
if (selNum!=2)
{
m_app->dispToConsole("Please select two cloud!",ccMainAppInterface::ERR_CONSOLE_MESSAGE);
return;
} ccHObject* ent = selectedEntities[0];
assert(ent);
if (!ent || !ent->isA(CC_TYPES::POINT_CLOUD))
{
m_app->dispToConsole("Select a real point cloud!",ccMainAppInterface::ERR_CONSOLE_MESSAGE);
return;
}
ccHObject* ent2 = selectedEntities[1];
assert(ent2);
if (!ent2 || !ent2->isA(CC_TYPES::POINT_CLOUD))
{
m_app->dispToConsole("Select a real point cloud!",ccMainAppInterface::ERR_CONSOLE_MESSAGE);
return;
} ccPointCloud* m_target_cloud = static_cast<ccPointCloud*>(ent);
ccPointCloud* m_Source_cloud = static_cast<ccPointCloud*>(ent2); //input cloud
unsigned count = m_target_cloud->size();
bool hasNorms = m_target_cloud->hasNormals();
CCVector3 bbMin, bbMax;
m_target_cloud->getBoundingBox(bbMin,bbMax);
const CCVector3d& globalShift = m_target_cloud->getGlobalShift();
double globalScale = m_target_cloud->getGlobalScale(); cc3DNdtdlg dlg;
if (!dlg.exec())
return; double maxCorrDis =1;
maxCorrDis= dlg.getVoxelGridsize();
pcl::PointCloud<PointXYZ>::Ptr pcl_t_cloud (new pcl::PointCloud<PointXYZ>);
pcl::PointCloud<PointXYZ>::Ptr pcl_s_cloud (new pcl::PointCloud<PointXYZ>);
try
{
//
unsigned pointCount = m_target_cloud->size();
pcl_t_cloud->resize(pointCount); for (unsigned i = 0; i < pointCount; ++i)
{
const CCVector3* P = m_target_cloud->getPoint(i);
pcl_t_cloud->at(i).x = static_cast<float>(P->x);
pcl_t_cloud->at(i).y = static_cast<float>(P->y);
pcl_t_cloud->at(i).z = static_cast<float>(P->z);
}
//
pointCount = m_Source_cloud->size();
pcl_s_cloud->resize(pointCount); for (unsigned i = 0; i < pointCount; ++i)
{
const CCVector3* P = m_Source_cloud->getPoint(i);
pcl_s_cloud->at(i).x = static_cast<float>(P->x);
pcl_s_cloud->at(i).y = static_cast<float>(P->y);
pcl_s_cloud->at(i).z = static_cast<float>(P->z);
}
}
catch(...)
{
//any error (memory, etc.)
pcl_t_cloud.reset();
pcl_s_cloud.reset();
}
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree1 (new pcl::search::KdTree<pcl::PointXYZ>);
tree1->setInputCloud (pcl_t_cloud);
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree2 (new pcl::search::KdTree<pcl::PointXYZ>);
tree2->setInputCloud (pcl_s_cloud);
pcl::PolygonMesh::Ptr mesh(new pcl::PolygonMesh);
// reconstruct meshes for source and target
pcl::OrganizedFastMesh<pcl::PointXYZ> fast_mesh;
fast_mesh.setInputCloud(pcl_t_cloud); //设置输入点云
/* ofm.setIndices(cloudInd);*/ //设置输入点云索引
fast_mesh.setMaxEdgeLength(0.1); //设置多边形网格最大边长
fast_mesh.setTriangulationType(pcl::OrganizedFastMesh<pcl::PointXYZ>::TRIANGLE_ADAPTIVE_CUT);//设置网格类型
fast_mesh.setTrianglePixelSize(1); //设置三角形边长 1表示链接相邻点作为边长
//fast_mesh.storeShadowedFaces(false); //设置是否存储阴影面
fast_mesh.setSearchMethod(tree1);
fast_mesh.reconstruct(*mesh);
// compute normals and covariances for source and target
pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
boost::shared_ptr<std::vector<Eigen::Matrix3d, Eigen::aligned_allocator<Eigen::Matrix3d> >> target_covariances(new std::vector<Eigen::Matrix3d, Eigen::aligned_allocator<Eigen::Matrix3d> >);
pcl::features::computeApproximateNormals(*pcl_t_cloud, mesh->polygons, *normals);
pcl::features::computeApproximateCovariances(*pcl_t_cloud, *normals, *target_covariances); fast_mesh.setInputCloud(pcl_s_cloud);
/* ofm.setIndices(cloudInd);*/ //设置输入点云索引
fast_mesh.setMaxEdgeLength(1.0); //设置多边形网格最大边长
fast_mesh.setTriangulationType(pcl::OrganizedFastMesh<pcl::PointXYZ>::TRIANGLE_ADAPTIVE_CUT);//设置网格类型
fast_mesh.setTrianglePixelSize(1); //设置三角形边长 1表示链接相邻点作为边长
fast_mesh.storeShadowedFaces(false); //设置是否存储阴影面
fast_mesh.setSearchMethod(tree2);
fast_mesh.reconstruct(*mesh);
// compute normals and covariances for source and target
pcl::PointCloud<pcl::Normal>::Ptr normalst(new pcl::PointCloud<pcl::Normal>);
boost::shared_ptr<std::vector<Eigen::Matrix3d, Eigen::aligned_allocator<Eigen::Matrix3d>>> source_covariances(new std::vector<Eigen::Matrix3d, Eigen::aligned_allocator<Eigen::Matrix3d> >);
pcl::features::computeApproximateNormals(*pcl_s_cloud, mesh->polygons, *normalst);
pcl::features::computeApproximateCovariances(*pcl_s_cloud, *normalst, *source_covariances);
// setup Generalized-ICP
pcl::GeneralizedIterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> gicp;
gicp.setMaxCorrespondenceDistance(maxCorrDis);
gicp.setInputSource(pcl_s_cloud);
gicp.setInputTarget(pcl_t_cloud);
/*gicp.setSourceCovariances(source_covariances);
gicp.setTargetCovariances(target_covariances);*/
// run registration and get transformation
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_out (new pcl::PointCloud<pcl::PointXYZ>);
gicp.align(*cloud_out);
Eigen::Matrix4f transform = gicp.getFinalTransformation();
int pointCount = cloud_out->size(); //static_cast<size_t>(sm_cloud ? sm_cloud->width * sm_cloud->height : 0); ccPointCloud* ccCloud =new ccPointCloud();
if (!ccCloud->reserve(static_cast<unsigned>(pointCount)))
return ;
for (size_t i = 0; i < pointCount; ++i)
{
CCVector3 P(cloud_out->at(i).x,cloud_out->at(i).y,cloud_out->at(i).z);
ccCloud->addPoint(P);
}
ccCloud->setName(QString("GICP"));
ccColor::Rgb col = ccColor::Generator::Random();
ccCloud->setRGBColor(col);
ccCloud->showColors(true);
ccCloud->setPointSize(1);
ccHObject* group = 0;
if (!group)
group = new ccHObject(QString("GICP(%1)").arg(ent2->getName()));
group->addChild(ccCloud);
group->setVisible(true);
m_app->addToDB(group);
}

   

近似特征值计算

这个的原理被想复杂了,就是特征值分解的逆步骤,形成了三个正交的向量,epsilon是最小的特征值,法向量是最小的特征向量。

本来求法向量的过程就是根据近邻的k个点,利用主成分分析PCA进行计算得到特征值最小的那个特征向量作为法向量。

/** \brief Compute GICP-style covariance matrices given a point cloud and
* the corresponding surface normals.
* \param[in] cloud Point cloud containing the XYZ coordinates,
* \param[in] normals Point cloud containing the corresponding surface normals.
* \param[out] covariances Vector of computed covariances.
* \param[in] Optional: Epsilon for the expected noise along the surface normal (default: 0.001)
*/
template <typename PointT, typename PointNT> inline void
computeApproximateCovariances(const pcl::PointCloud<PointT>& cloud,
const pcl::PointCloud<PointNT>& normals,
std::vector<Eigen::Matrix3d, Eigen::aligned_allocator<Eigen::Matrix3d> >& covariances,
double epsilon = 0.001)
{
assert(cloud.points.size() == normals.points.size()); int nr_points = static_cast<int>(cloud.points.size());
covariances.resize(nr_points);
for (int i = 0; i < nr_points; ++i)
{
Eigen::Vector3d normal(normals.points[i].normal_x,
normals.points[i].normal_y,
normals.points[i].normal_z); // compute rotation matrix
Eigen::Matrix3d rot;
Eigen::Vector3d y;
y << 0, 1, 0;
rot.row(2) = normal;
y = y - normal(1) * normal;
y.normalize();
rot.row(1) = y;
rot.row(0) = normal.cross(rot.row(1)); // comnpute approximate covariance
Eigen::Matrix3d cov;
cov << 1, 0, 0,
0, 1, 0,
0, 0, epsilon;
covariances[i] = rot.transpose()*cov*rot;
}
} }

  

[PointCloud] GICP的更多相关文章

  1. ros pcl sensor::pointcloud2 转换成pcl::pointcloud

    #include <pcl_conversions/pcl_conversions.h> #include <pcl/point_types.h> #include <p ...

  2. How to publish a pointcloud of ros msgs in a topic from a pcd file?

    How to publish a pointcloud of ros msgs in a topic from a pcd file? Two methods 1. modified source 2 ...

  3. [转]ROS 传感器消息及RVIZ可视化Laserscan和PointCloud

    https://blog.csdn.net/yangziluomu/article/details/79576508 https://answers.ros.org/question/60239/ho ...

  4. 论文笔记:(2019)LDGCNN : Linked Dynamic Graph CNN-Learning on PointCloud via Linking Hierarchical Features

    目录 摘要 一.引言 A.基于视图的方法 B.基于体素的方法 C.基于几何的方法 二.材料 三.方法 A.问题陈述 B.图生成 C.图特征提取 D.变换不变函数 E.LDGCNN架构 F.冻结特征提取 ...

  5. pointcloud(点云)与mesh(面元)模型的区别

    点元与面元

  6. PointCloud及其经典论文介绍

    这篇博客会介绍点云的基本知识,重点介绍最近两年发表的部分经典论文,有什么建议欢迎留言! 点云基本介绍 点云是某个坐标系下的点的数据集,包含了丰富的信息,可以是三维坐标X,Y,Z.颜色.强度值.时间等等 ...

  7. pcl曲面网格模型的三种显示方式

    pcl网格模型有三种可选的显示模式,分别是面片模式(surface)显示,线框图模式(wireframe)显示,点模式(point)显示.默认为面片模式进行显示.设置函数分别为: void pcl:: ...

  8. pcl计算样点法向并显示

    利用最小二乘法估计样点表面法向,并显示 #include <pcl/point_types.h> #include <pcl/io/pcd_io.h> #include < ...

  9. pcl曲面重建模块-poisson重建算法示例

    poisson曲面重建算法 pcl-1.8测试通过 #include <iostream> #include <pcl/common/common.h> #include &l ...

随机推荐

  1. HDU 3333 & 离线+线段树

    题意: 统计一段区间内不同数字之和.如1 1 2 3 1 统计2---5即1+2+3. SOL: 很少打过离线的题目...这种可离线可在线的题不管怎么样一般都是强行在线... 考虑这题,此前做过一个类 ...

  2. HDU 3074 (线段树+模P乘法)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3074 题目大意:单点更新.维护序列乘法.mod 1000000007. 解题思路: 10000000 ...

  3. Codeforces Round #209 (Div. 2) B. Permutation

    解题思路: 如果序列a是单调递增的,则序列为1,2,..... 2n,则将给出的式子化简得Σ(a2i - a2i-1) = n 如果序列a是单调递减的,则序列为2n,.........2, 1,则将给 ...

  4. Jquery Ajax方法传值到action

    假设cshtml文件中是这样的: <script type="text/javascript"> $(document).ready(function(){ $(&qu ...

  5. CSS去除firefox点击链接时的虚线边框

    a { outline: none; } 或者缩小范围: a:focus { outline: none; }

  6. Unix NetWork Programming -- 环境搭建(Ubuntu 12.04 x86_64)

    1. 下载源代码:http://www.ituring.com.cn/book/download/60498ad9-ede6-4023-a92b-04d47be23578 2. 解压文件后进入文件根目 ...

  7. [LintCode] Wiggle Sort II 扭动排序之二

    Given an unsorted array nums, reorder it such that nums[0] < nums[1] > nums[2] < nums[3]... ...

  8. ellipsis

    语法:  text-overflow : clip | ellipsis 参数:  clip : 不显示省略标记(...),而是简单的裁切(clip这个参数是不常用的!)      ellipsis ...

  9. sqlmap用户手册详解(转)

    http://url/sqlmap/mysql/get_int.php?id=1 当给sqlmap这么一个url的时候,它会: 1.判断可注入的参数 2.判断可以用那种SQL注入技术来注入 3.识别出 ...

  10. 在win7下安装unbuntu系统

    1.分盘 准备EasyBCD,ubuntu操作系统 配置EasyBCD,安装ubuntu http://www.linuxidc.com/Linux/2014-04/100369.htm http:/ ...