之前有篇博客講到八叉樹的重要性,其基本涉及到了點雲算法的方方面面,點雲數據在空間上雜亂無序,因為其在空間上並不存在任何拓撲關系,原始點雲數據僅僅是該空間內的所有數據點一個簡單的集合。八叉樹的構建以及其近鄰搜索的方法解決了點雲數據雜亂無序的問題,讓各數據點與其鄰域點建立聯系,構建八叉樹索引后的各數據點從此不再孤立,類似於找到了各自的“組織關系”,而且相當一部分算法需要對每一個數據點作相應的一些操作,我們在對數據點的某些空間屬性做相應的描述時,那么必須依賴其鄰域點。
上面又一次論述構建空間索引的重要性,當然也不是為了湊字數,畢竟這個是算法的前置工作,作為背景還是得再次交代一下,那么構建局部坐標系的意義在哪?
我先舉幾個常見的例子,數據點及其鄰域點模型的擬合、增采樣插值、移動最小二乘擬合、邊界點檢測以及三維構網,所以在我們獲取到相應的鄰域數據點集后,我們還需要建立局部的坐標系來進行相應的模型擬合,一般以該點集擬合的平面的法線作為該局部坐標系下的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);