点云算法-局部坐标系的构建
之前有篇博客讲到八叉树的重要性,其基本涉及到了点云算法的方方面面,点云数据在空间上杂乱无序,因为其在空间上并不存在任何拓扑关系,原始点云数据仅仅是该空间内的所有数据点一个简单的集合。八叉树的构建以及其近邻搜索的方法解决了点云数据杂乱无序的问题,让各数据点与其邻域点建立联系,构建八叉树索引后的各数据点从此不再孤立,类似于找到了各自的“组织关系”,而且相当一部分算法需要对每一个数据点作相应的一些操作,我们在对数据点的某些空间属性做相应的描述时,那么必须依赖其邻域点。
上面又一次论述构建空间索引的重要性,当然也不是为了凑字数,毕竟这个是算法的前置工作,作为背景还是得再次交代一下,那么构建局部坐标系的意义在哪?
我先举几个常见的例子,数据点及其邻域点模型的拟合、增采样插值、移动最小二乘拟合、边界点检测以及三维构网,所以在我们获取到相应的邻域数据点集后,我们还需要建立局部的坐标系来进行相应的模型拟合,一般以该点集拟合的平面的法线作为该局部坐标系下的Z轴,然后利用正交化构建垂直于Z轴的X轴,在Z、X轴确定的情况下再构建Y,一般选择当前要处理的数据点(或者点集的重心)作为该局部坐标系的圆心O,到此为止,局部坐标系建立完成。然后建立的局部坐标系构建相应的拟合模型,然后可以在模型上进行相应的插值,从而可以对点云模型进行人为改造,譬如增采样、平滑等操作。
局部坐标系 的构建:根据已知的法线,然后根据施密特正交化进行分解,pcl里提供对应的接口,也很好用
inline void getCoordinateSystemOnPlane (const PointNT &p_coeff, Eigen::Vector4f &u, Eigen::Vector4f &v)
{
pcl::Vector4fMapConst p_coeff_v = p_coeff.getNormalVector4fMap ();
v = p_coeff_v.unitOrthogonal ();
u = p_coeff_v.cross3 (v);
}
Eigen::Vector4f u = Eigen::Vector4f::Zero (), v = Eigen::Vector4f::Zero (); // Obtain a coordinate system on the least-squares plane //v = normals_->points[(*indices_)[idx]].getNormalVector4fMap ().unitOrthogonal (); //u = normals_->points[(*indices_)[idx]].getNormalVector4fMap ().cross3 (v); getCoordinateSystemOnPlane (normals_->points[(*indices_)[idx]], u, v);