RoPs(Rotational Projection Statistics)

pcl官网地址
来自:
《pcl_点云从入门到精通》:详见这里
旋装投影特征

  • 旋装平移不变性
  • 抗干扰性良好

关键点

  • 给定关键点PPP和其支撑半径内rrr内的点,得到NNN个三角形和MMM个顶点
  • 对于第i个三角形见上图,三角形中任意一个顶点可以表示为:
    pi(s,t)=pi1+s(pi2−pi1)+t(pi3−ppi1)(0≤s,t≤1;s+t≤1)p_i(s,t)=p_{i1}+s(p_{i2}-p_{i1})+t(p_{i3}-p_{p_{i1}}) (0 \leq s,t \leq 1;s+t\leq 1)pi​(s,t)=pi1​+s(pi2​−pi1​)+t(pi3​−ppi1​​)(0≤s,t≤1;s+t≤1)
  • 第i个三角形上的单点的散布矩阵CiC_iCi​为:
    Ci=112∑j=13∑k=13(pij−p)(pik−p)T+112∑j=13(pij−p)(pij−p)TC_i =\frac{1}{12}\sum_{j=1}^3\sum_{k=1}^3(p_{ij}-p)(p_{ik}-p)^T+\frac{1}{12}\sum_{j=1}^{3}(p_{ij}-p)(p_{ij}-p)^TCi​=121​j=1∑3​k=1∑3​(pij​−p)(pik​−p)T+121​j=1∑3​(pij​−p)(pij​−p)T
    总散布矩阵为:
    wi1:w_{i1}:wi1​:三角形面积与局部表面SSS总面积的比值
    wi2:w_{i2}:wi2​:关键点到第i个三角形中心距离,形成的权值
    C=∑i=1Nwi1wi2Ciwi1=∣(pi2−pi1)×(pi3−pi1)∣∑i=1N∣(pi2−pi1)×(pi3−pi1)∣∣wi2=(r−∣p−pi1+pi2+pi33∣)2C=\sum_{i=1}^{N}w_{i1}w_{i2}C_i\\ w_{i1}=\frac{|(p_{i2}-p_{i1})×(p_{i3}-p_{i1})|}{\sum^N_{i=1}|(p_{i2}-p_{i1})×(p_{i3}-p_{i1})||}\\ w_{i2}=(r-|p-\frac{p_{i1}+p_{i2}+p_{i3}}{3}|)^2C=i=1∑N​wi1​wi2​Ci​wi1​=∑i=1N​∣(pi2​−pi1​)×(pi3​−pi1​)∣∣∣(pi2​−pi1​)×(pi3​−pi1​)∣​wi2​=(r−∣p−3pi1​+pi2​+pi3​​∣)2
  • 在对特征矩阵进行分解
    E:E:E:特征值矩阵 降序排列
    V:V:V:特征向量 对应特征值
    CE=EVCE=EVCE=EV
  • 特征向量方向:
    多数散布向量所指向的方向,可以根据特征向量与散布向量的内积得到一个模糊特征向量,其局部坐标为:
    ∼v1=v1∗sign(∑i=1Nwi1wi2(16∑j=13(pij−p)v1))\begin{array}{c} \sim\\ v_{1} \end{array}=v_1*sign(\sum_{i=1}^Nw_{i1}w_{i2}(\frac {1}{6}\sum_{j=1}^3(p_{ij}-p)v_1))∼v1​​=v1​∗sign(i=1∑N​wi1​wi2​(61​j=1∑3​(pij​−p)v1​))
    ∼v3=v3∗sign(∑i=1Nwi1wi2(16∑j=13(pij−p)v3))\begin{array}{c} \sim\\ v_{3} \end{array}=v_3*sign(\sum_{i=1}^Nw_{i1}w_{i2}(\frac {1}{6}\sum_{j=1}^3(p_{ij}-p)v_3))∼v3​​=v3​∗sign(i=1∑N​wi1​wi2​(61​j=1∑3​(pij​−p)v3​))
    v2=v1×v3v_{2}=v_1×v_3v2​=v1​×v3​

描述符

输入点云或者其mesh,计算点ppp及其支撑半径为rrr的局部表面,再进算其局部参考坐标系,再将局部表面SSS上的三角形顶点构成点云QQQ,映射到局部参考坐标系Q′Q'Q′.
具体步骤:
Q:Q:Q:原始点云
Q′:Q':Q′:转换到局部坐标系的点云

  1. 旋装点云Q′Q'Q′绕x轴旋转θk\theta_kθk​,得到旋转后的点云Q′(θk)Q'(\theta_k)Q′(θk​),再将Q′(θk)Q'(\theta_k)Q′(θk​)获得其的三视图xy,xz,yzxy,xz,yzxy,xz,yz及其对应投影点云Qi′(θk)~;i=1,2,3\tilde{Q_i'(\theta_k)};i=1,2,3Qi′​(θk​)~​;i=1,2,3
  2. 对于每个Qi′(θk)~;i=1,2,3\tilde{Q_i'(\theta_k)};i=1,2,3Qi′​(θk​)~​;i=1,2,3,将其二位包围框均匀划分为L×LL×LL×L个单元格,统计落入每个单元格点的个数,得到一个L×LL×LL×L的矩阵DDD,将矩阵DDD归一化使所有单元格数量为1,使其对于分辨率具有不变性。
  3. 提取分布矩阵DDD的中心矩和香农熵。
    中心矩公式umnu_{mn}umn​:
    umn=∑i=1L∑j=1L(i−i‾)m(j−j‾)nD(i,j)u_{mn}=\sum_{i=1}^L\sum_{j=1}^L(i-\overline i)^m(j-\overline j)^n D(i,j)umn​=i=1∑L​j=1∑L​(i−i)m(j−j​)nD(i,j)
    香农熵为eee:
    e=−∑i=1L∑j=1LD(i,j)log(D(i,j))e=-\sum_{i=1}^L\sum_{j=1}^LD(i,j)log(D(i,j))e=−i=1∑L​j=1∑L​D(i,j)log(D(i,j))
    在将三视图xy,xz,yzxy,xz,yzxy,xz,yz上的三个统计向量组合起来的得到fx(θk),k:表示绕x轴旋装k次f_x{(\theta_k)},k:表示绕x轴旋装k次fx​(θk​),k:表示绕x轴旋装k次
  4. 分别绕x轴旋主k次k=1,..,Tk=1,..,Tk=1,..,T,其角度分别为θk\theta_kθk​,得到其k次的关于3个平面的投影fx(θk),fy(θk),fz(θk)f_x{(\theta_k)},f_y{(\theta_k)},f_z{(\theta_k)}fx​(θk​),fy​(θk​),fz​(θk​),最终得到描述符:
    f={fx(θk),fy(θk),fz(θk)}f=\{f_x{(\theta_k)},f_y{(\theta_k)},f_z{(\theta_k)}\}f={fx​(θk​),fy​(θk​),fz​(θk​)}
  5. 上述参数中L(划分区域)=5L(划分区域)=5L(划分区域)=5,T(旋转次数)=3T(旋转次数)=3T(旋转次数)=3,如果输入是点云需要将其三角化/采用其他算法的局部参考坐标模块

pcl中使用

其他文件详见pcl点云从入门到精通

#include <pcl/features/rops_estimation.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/histogram_visualizer.h>
#include <pcl/visualization/pcl_plotter.h>
#include <iostream>
using namespace pcl;
using namespace std;
int main(int argc, char const *argv[])
{pcl::PointCloud<PointXYZ>::Ptr  cloud(new  pcl::PointCloud<PointXYZ>());//pcl::io::loadPCDFile("/home/n1/notes/pcl/RoPS/test.pcd",*cloud);pcl::PointIndicesPtr   indices =   boost::shared_ptr<PointIndices>(new pcl::PointIndices());std::ifstream   indices_file;std::cout<<cloud->size()<<endl;indices_file.open("/home/n1/notes/pcl/RoPS/indices.txt",std::ifstream::in);//读取行数,并将索引添至队列for(std::string line;std::getline(indices_file,line);){std::istringstream in(line);unsigned    int index = 0;in >> index;indices->indices.push_back(index-1);}//关闭文件indices_file.close();std::vector<pcl::Vertices>  triangles;// std::vector<uint32_t>std::ifstream   triangles_file;triangles_file.open("/home/n1/notes/pcl/RoPS/triangles.txt",std::ifstream::in);//读取三角化信息for(std::string line;std::getline(triangles_file,line);){pcl::Vertices   triangle;std::istringstream  in(line);unsigned    int vertex  =0;//为每个id添加索引in  >>vertex;triangle.vertices.push_back(vertex-1);in  >> vertex;triangle.vertices.push_back(vertex-1);in  >>  vertex;triangle.vertices.push_back(vertex-1);triangles.push_back (triangle);}float support_radius    =   0.0285f;unsigned    int number_of_partition_bins    = 5;//分块大小unsigned    int number_of_rotations     =3;//旋转区域个数pcl::search::KdTree<PointXYZ>::Ptr  search_method(new  pcl::search::KdTree<PointXYZ>());search_method->setInputCloud(cloud);pcl::ROPSEstimation <pcl::PointXYZ,pcl::Histogram<135> > Feature_estimator;//估计特征点Feature_estimator.setSearchMethod(search_method);   //设置搜索方法Feature_estimator.setSearchSurface(cloud);          //设置搜索平面Feature_estimator.setInputCloud(cloud);             //设置输入点云Feature_estimator.setIndices(indices);              //对应的id索引Feature_estimator.setTriangles (triangles);         //设置三角化Feature_estimator.setRadiusSearch(support_radius);  //查找半径Feature_estimator.setNumberOfPartitionBins(number_of_partition_bins);//设置分块大小Feature_estimator.setNumberOfRotations (number_of_rotations);//旋转次数Feature_estimator.setSupportRadius(support_radius); //支撑半径pcl::PointCloud<pcl::Histogram <135> >::Ptr histograms (new pcl::PointCloud <pcl::Histogram <135> > ());Feature_estimator.compute(*histograms);std::cout<<histograms->header<<endl;pcl::visualization::PCLPlotter *plotter = new pcl::visualization::PCLPlotter ("test");plotter->setShowLegend(true);plotter->addFeatureHistogram<pcl::Histogram<135> >(*histograms,135,"rops");//点云,描述子长度,对应的id, 第0个点对应索引plotter->spin();return 0;
}

基于惯性矩和偏心率的描述子

官网链接
使用 pcl::MomentOfInertiaEstimation 类获取,惯性矩和偏心率描述子同时产生OBB(不一定为最小)和AABB边框

  1. 面积矩:来自
    SZ:S_Z:SZ​:平面图形对于z轴的面积距
    A:A:A:图形面积,位于yozyozyoz平面
    yc:yc:yc:面积中心到z轴的距离
    SZ=A×yc(单位m3)S_Z=A×yc(单位m^3)SZ​=A×yc(单位m3)

  2. 惯性矩:

    • 物理量:用作描述物体抵抗扭动转动的能力,单位(m4m^4m4):地址
    • 详细定义:面积与与轴的距离(形心到坐标轴)的平方和的乘机:地址
    • Ix:I_x:Ix​:平面图形对于z轴的面积矩,Iy:I_y:Iy​:平面图形对于y轴的面积矩
      Ix=∫Ay2dA,Iy=∫Ax2dAI_x=\int_Ay^2dA,I_y=\int_Ax^2dAIx​=∫A​y2dA,Iy​=∫A​x2dA
  3. 偏心率(离心率)

    • 描述圆锥曲线轨道形状的数学量:详见
  4. OBB(Oriented Bounding Box)方向包围盒,AaBB(Axis-Aligned Bounding Box)坐标对齐包围盒
    简介:地址1,地址2
    常用做作快速碰撞检测

  5. PCL中的原理简介

    • 先计算点云的协防差矩阵,分解求解特征值和特征向量(同时归一化)
    • 建立坐标系:特征向量从大到小对应的特征向量为:X,Y,ZX,Y,ZX,Y,Z,同时符合右手定则
    • X轴绕其他Y,Z轴旋转,一般是绕y轴旋转0−900-900−90,绕z轴旋转0−3600-3600−360,pcl可以设置,没旋转一次,
      • 惯性矩:每旋转一次,以X作为当前轴计算一次
      • 偏心率:每旋转一次,以X轴旋转后的正方向,作为假设平面的法向量,将点云投影到该假设平面,长轴与短轴由投影后点云的协防差矩阵得到
  6. pcl中代码(来自pcl点云入门到精通)

#include <pcl/features/moment_of_inertia_estimation.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/point_cloud.h>
using namespace pcl;
using namespace std;int main(int argc, char const *argv[])
{pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>());pcl::io::loadPCDFile("/home/n1/notes/pcl/inertia/test.pcd",*cloud);pcl::MomentOfInertiaEstimation<pcl::PointXYZ> feature_extractor;//特征提取feature_extractor.setInputCloud(cloud); //输入点云feature_extractor.compute ();           //计算std::vector<float>  moment_of_inertia;//惯性值std::vector<float>  eccentricity;     //偏心率pcl::PointXYZ min_point_AABB;           //AABB左下角坐标pcl::PointXYZ max_point_AABB;           //AABB右上角坐标pcl::PointXYZ min_point_OBB;            //OBB最小角坐标pcl::PointXYZ max_point_OBB;            //OBB右上角坐标pcl::PointXYZ position_OBB;             //OBB 局部坐标中心点Eigen::Matrix3f rotational_matrix_OBB;  //OBB方向float major_value, middle_value, minor_value;//三个特征值Eigen::Vector3f major_vector, middle_vector, minor_vector;//三个特征向量Eigen::Vector3f mass_center;    //质点feature_extractor.getMomentOfInertia(moment_of_inertia); //获取惯性矩feature_extractor.getEccentricity(eccentricity);                    //获得偏心率feature_extractor.getAABB(min_point_AABB,max_point_AABB);   //获取对应边框feature_extractor.getOBB(min_point_OBB,max_point_OBB,position_OBB,rotational_matrix_OBB);//feature_extractor.getEigenValues(major_value, middle_value, minor_value);   //获取特征值feature_extractor.getEigenVectors(major_vector, middle_vector, minor_vector);   //获取特征向量feature_extractor.getMassCenter(mass_center);       //质心//可视化boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer (new pcl::visualization::PCLVisualizer ("MomentOfInertiaEstimation"));viewer->setBackgroundColor (1, 1, 1);viewer->addCoordinateSystem (1.0);viewer->initCameraParameters ();viewer->addPointCloud<pcl::PointXYZ> (cloud,pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>(cloud,0,255,0), "sample cloud");viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE,5,"sample cloud");viewer->addCube (min_point_AABB.x, max_point_AABB.x, min_point_AABB.y, max_point_AABB.y, min_point_AABB.z, max_point_AABB.z, 1.0, 0.0, 0.0, "AABB");viewer->setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_OPACITY,0.1,"AABB"); //不透明度viewer->setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_LINE_WIDTH,4,"AABB");    //线宽Eigen::Vector3f position (position_OBB.x, position_OBB.y, position_OBB.z);std::cout<<"局部坐标中心点: "<<position_OBB<<endl;std::cout<<"质心: "<<mass_center<<endl;Eigen::Quaternionf quat (rotational_matrix_OBB);    //将方向转化为矢量viewer->addCube (position, quat, max_point_OBB.x - min_point_OBB.x, max_point_OBB.y - min_point_OBB.y, max_point_OBB.z - min_point_OBB.z, "OBB");viewer->setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR,0,0,1,"OBB");viewer->setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_OPACITY,0.1,"OBB");viewer->setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_LINE_WIDTH,4,"OBB");//viewer->setRepresentationToWireframeForAllActors(); //改变为线框表示pcl::PointXYZ center (mass_center (0), mass_center (1), mass_center (2));pcl::PointXYZ x_axis (major_vector (0) + mass_center (0), major_vector (1) + mass_center (1), major_vector (2) + mass_center (2));pcl::PointXYZ y_axis (middle_vector (0) + mass_center (0), middle_vector (1) + mass_center (1), middle_vector (2) + mass_center (2));pcl::PointXYZ z_axis (minor_vector (0) + mass_center (0), minor_vector (1) + mass_center (1), minor_vector (2) + mass_center (2));viewer->addLine (center, x_axis, 1.0f, 0.0f, 0.0f, "major eigen vector");viewer->addLine (center, y_axis, 0.0f, 1.0f, 0.0f, "middle eigen vector");viewer->addLine (center, z_axis, 0.0f, 0.0f, 1.0f, "minor eigen vector");std::cout<<"size of cloud :"<<cloud->points.size()<<endl;std::cout<<"moment_of_inertia :"<<moment_of_inertia.size()<<endl;std::cout<<"eccentricity :"<<eccentricity.size()<<endl;while(!viewer->wasStopped()){viewer->spinOnce (100);boost::this_thread::sleep (boost::posix_time::microseconds (100000));}return 0;
}

PCL点云学习 十二(RoPs 特征与惯性矩描述子)相关推荐

  1. OpenCV与图像处理学习十二——图像形状特征之HOG特征

    OpenCV与图像处理学习十二--图像形状特征之HOG特征 一.图像特征理解 1.1 颜色特征 1.2 纹理特征 1.3 形状特征 1.4 空间关系特征 二.形状特征描述 2.1 HOG特征 2.1. ...

  2. OpenCV与图像处理学习十四——SIFT特征(含代码)

    OpenCV与图像处理学习十四--SIFT特征(含代码) 一.SIFT算法 二.SIFT实现过程 三.代码实现 一.SIFT算法 SIFT, 即尺度不变特征变换算法(Scale-invariant f ...

  3. PyTorch框架学习十二——损失函数

    PyTorch框架学习十二--损失函数 一.损失函数的作用 二.18种常见损失函数简述 1.L1Loss(MAE) 2.MSELoss 3.SmoothL1Loss 4.交叉熵CrossEntropy ...

  4. (转)SpringMVC学习(十二)——SpringMVC中的拦截器

    http://blog.csdn.net/yerenyuan_pku/article/details/72567761 SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter, ...

  5. 【FastAPI 学习十二】定时任务篇 (移步博客园或个人网站 无广告,界面清爽整洁)

    声明 目前个人放弃CSDN平台,文章只发布于个人网站和博客园 博客园地址 [FastAPI 学习十二]定时任务篇

  6. C1认证学习十二(网络拓扑)

    C1认证学习十二(网络拓扑) 任务背景 互联网是一个广义的概念,它泛指是一切通过网路连接在一起的计算机的集合,所以,若果只是局部观察,那就不能再说互联网是一个互联的了,那么,如果说对于一个公司来说,具 ...

  7. Js高级程序设计第三版学习(十二章)

                                  Js高级程序设计第三版学习(十二章) 第十二章 DOM2和DOM3   1.样式: 访问样式属性 任何支持style特性的HTML元素都有一 ...

  8. PCL:描述三维离散点的ROPS特征(Code)

    前言: 三维点云为三维欧式空间点的集合.对点云的形状描述若使用局部特征,则可分为两种:固定世界坐标系的局部描述和寻找局部主方向的局部描述,ROPS特征为寻找局部主方向的特征描述. 1.寻找主方向(对X ...

  9. linux中ftp的工作原理,Linux系统学习 十二、VSFTP服务—简介与原理

    1.简介与原理 互联网诞生之初就存在三大服务:WWW.FTP.邮件 FTP主要针对企业级,可以设置权限,对不同等级的资料针对不同权限人员显示. 但是像网盘这样的基本没有权限划分. 简介: FTP(Fi ...

最新文章

  1. 中国新十大军工企业名单及简称
  2. 浅谈代码的执行效率(1):算法是关键
  3. 004-cpu的区分
  4. 四十二、深入Java中的文件读取操作
  5. linux下屏幕太靠右了,怎么消除linux下的屏幕偏移现象和调整屏幕刷新率?
  6. 【转】PCA算法学习_1(OpenCV中PCA实现人脸降维)
  7. CSS常见的四种垂直居中的方法
  8. 计算机java培训总结,java培训总结范文
  9. 哈工大人工智能研究院院长刘劼:AIoT 核心在“智”不在“联”,需云边端协同...
  10. 【NOIP2013】【Luogu1980】计数问题
  11. 平凡的世界电子书pdf下载_零基础彩铅画入门教程步骤图及全套PDF电子书教程下载!...
  12. cad插件_CAD插件自动标注安装教程
  13. 【老生谈算法】基于主成分分析PCA的matlab人脸识别系统设计与算法原理(论文+程序源码)——人脸识别算法
  14. rtsp连接断开_海康RTSP客户端连接分析
  15. python写一个木马_Python编写简易木马程序 - 博客频道 - CSDN.NET
  16. 数据字典的作用和定义(软件工程)
  17. 介绍中国传统节日的网页html,中国传统节日介绍:中秋节
  18. 收我叫mt3完整源码,不要拿网上的来忽悠,要求前后端完整,文档工具完整,重点可演示编译成功!联系我!
  19. [应用推荐]FreeMind自动生成系统盘的树状图(思维导图)
  20. android 触控优化,太滑手了,安卓这款触控优化神器要逆天!

热门文章

  1. TDD—LTE和FDD—LTE谁更先进?
  2. 小程序——扫普通链接二维码打开小程序
  3. 基于全景相机的视觉SLAM
  4. 票务管理系统项目(part1)
  5. dac7714和dac3152两种DAC芯片FPGA控制流程记录
  6. 提高模具寿命需控制环节
  7. Angularjs日程表操作2
  8. 七、如何区分点击与滑动
  9. 【Java】——基础算法Java代码
  10. Clonezilla--系统克隆