PCL包围盒(详细介绍)

实现效果:

原理分析:
1.包围盒简介
  包围盒也叫外接最小矩形,是一种求解离散点集最优包围空间的算法,基本思想是用体积稍大且特性简单的几何体(称为包围盒)来近似地代替复杂的几何对象。
  常见的包围盒算法有AABB包围盒、包围球、方向包围盒OBB以及固定方向凸包FDH。碰撞检测问题在虚拟现实、计算机辅助设计与制造、游戏及机器人等领域有着广泛的应用,甚至成为关键技术。而包围盒算法是进行碰撞干涉初步检测的重要方法之一。

最小包围盒的计算过程大致如下:
1.利用PCA主元分析法获得点云的三个主方向,获取质心,计算协方差,获得协方差矩阵,求取协方差矩阵的特征值和特长向量,特征向量即为主方向。
2.利用1中获得的主方向和质心,将输入点云转换至原点,且主方向与坐标系方向重回,建立变换到原点的点云的包围盒。
3.给输入点云设置主方向和包围盒,通过输入点云到原点点云变换的逆变换实现。

PCA(Principal Component Analysis)主成分分析

主成分分析可以用来计算有多个变量组成的数据集的坐标系空间,数据集的多个变量可以分成多个不相关分量,存在一个顶点位置数组中的x,y,z坐标值就是这样的数据集(点云)。数据集中最不同的方向表示主分量的基本主元。
将每个点设为,点云就看作 N个点构成的数据集。首先利用以下公式计算位置平均数m

在构建一个协方差矩阵C,

协方差矩阵是由以下六个元素组成的对称矩阵:


协方差矩阵表示x,y,z坐标值之间的相互关系。若这三个坐标值两两无关,则他们在协方差矩阵上元素的值为0,为了将所有的点集中均匀的沿着坐标轴分布,需要将协方差矩阵转换成对角阵。我们可以利用线性代数里面的内容:

作为该对象自然轴对应的方向,下面计算出从顶点沿X、Y、Z三个方向最大和最小位置,根据这些最大值和最小值可以容易的构建出边界盒的六个平面。

为了确定最大和最小的范围,可以通过计算每个顶点位置坐标Pi与单位向量的内积来完成。边界盒的6个平面分别为:

边界盒的尺寸就是X,Y,Z三个方向上相应内积的最大值与最小值之差,边界盒的中心O就是三对反向平面中三个平面的交点,令a,b,c分别为X,Y,Z上最大值与最小值的平均值:


PCA在很多地方还可以用到,笔者觉得了协方差矩阵、特征值、特征向量的几何意义是理解PCA的关键。上述代码中还用到四元数,四元数主要用于旋转变化。

代码如下:

#include <pcl/features/moment_of_inertia_estimation.h>
#include <vector>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/cloud_viewer.h>
#include <boost/thread/thread.hpp>#include <pcl/visualization/cloud_viewer.h>int main (int argc, char** argv)
{if (argc != 2)return (0);pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ> ());if (pcl::io::loadPCDFile (argv[1], *cloud) == -1)return (-1);pcl::MomentOfInertiaEstimation <pcl::PointXYZ> feature_extractor;feature_extractor.setInputCloud (cloud); //default clouldfeature_extractor.compute ();std::vector <float> moment_of_inertia;  //¹ßÐÔ¾àstd::vector <float> eccentricity;  //ÀëÐÄÂÊpcl::PointXYZ min_point_AABB;pcl::PointXYZ max_point_AABB;pcl::PointXYZ min_point_OBB;pcl::PointXYZ max_point_OBB;pcl::PointXYZ position_OBB;Eigen::Matrix3f rotational_matrix_OBB;float major_value, middle_value, minor_value; //eigenÊǼÆËã¾ØÕóµÄ¿ªÔ´¿â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); //ÌØÕ÷ÌáÈ¡AABBfeature_extractor.getOBB (min_point_OBB, max_point_OBB, position_OBB, rotational_matrix_OBB); //ÌØÕ÷ÌáÈ¡OBBfeature_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 ("µãÔÆ¿âPCLѧϰ½Ì³ÌµÚ¶þ°æ-»ùÓÚ¹ßÐÔ¾ØÓëÆ«ÐÄÂʵÄÃèÊö×Ó"));boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer (new pcl::visualization::PCLVisualizer ("3D Viewer"));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: "<<position_OBB<<endl;std::cout<<"mass_center: "<<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;//Eigen::Vector3f p1 (min_point_OBB.x, min_point_OBB.y, min_point_OBB.z);//Eigen::Vector3f p2 (min_point_OBB.x, min_point_OBB.y, max_point_OBB.z);//Eigen::Vector3f p3 (max_point_OBB.x, min_point_OBB.y, max_point_OBB.z);//Eigen::Vector3f p4 (max_point_OBB.x, min_point_OBB.y, min_point_OBB.z);//Eigen::Vector3f p5 (min_point_OBB.x, max_point_OBB.y, min_point_OBB.z);//Eigen::Vector3f p6 (min_point_OBB.x, max_point_OBB.y, max_point_OBB.z);//Eigen::Vector3f p7 (max_point_OBB.x, max_point_OBB.y, max_point_OBB.z);//Eigen::Vector3f p8 (max_point_OBB.x, max_point_OBB.y, min_point_OBB.z);//p1 = rotational_matrix_OBB * p1 + position;//p2 = rotational_matrix_OBB * p2 + position;//p3 = rotational_matrix_OBB * p3 + position;//p4 = rotational_matrix_OBB * p4 + position;//p5 = rotational_matrix_OBB * p5 + position;//p6 = rotational_matrix_OBB * p6 + position;//p7 = rotational_matrix_OBB * p7 + position;//p8 = rotational_matrix_OBB * p8 + position;//pcl::PointXYZ pt1 (p1 (0), p1 (1), p1 (2));//pcl::PointXYZ pt2 (p2 (0), p2 (1), p2 (2));//pcl::PointXYZ pt3 (p3 (0), p3 (1), p3 (2));//pcl::PointXYZ pt4 (p4 (0), p4 (1), p4 (2));//pcl::PointXYZ pt5 (p5 (0), p5 (1), p5 (2));//pcl::PointXYZ pt6 (p6 (0), p6 (1), p6 (2));//pcl::PointXYZ pt7 (p7 (0), p7 (1), p7 (2));//pcl::PointXYZ pt8 (p8 (0), p8 (1), p8 (2));//viewer->addLine (pt1, pt2, 1.0, 0.0, 0.0, "1 edge");//viewer->addLine (pt1, pt4, 1.0, 0.0, 0.0, "2 edge");//viewer->addLine (pt1, pt5, 1.0, 0.0, 0.0, "3 edge");//viewer->addLine (pt5, pt6, 1.0, 0.0, 0.0, "4 edge");//viewer->addLine (pt5, pt8, 1.0, 0.0, 0.0, "5 edge");//viewer->addLine (pt2, pt6, 1.0, 0.0, 0.0, "6 edge");//viewer->addLine (pt6, pt7, 1.0, 0.0, 0.0, "7 edge");//viewer->addLine (pt7, pt8, 1.0, 0.0, 0.0, "8 edge");//viewer->addLine (pt2, pt3, 1.0, 0.0, 0.0, "9 edge");//viewer->addLine (pt4, pt8, 1.0, 0.0, 0.0, "10 edge");//viewer->addLine (pt3, pt4, 1.0, 0.0, 0.0, "11 edge");//viewer->addLine (pt3, pt7, 1.0, 0.0, 0.0, "12 edge");while(!viewer->wasStopped()){viewer->spinOnce (100);boost::this_thread::sleep (boost::posix_time::microseconds (100000));}return (0);
}

Compiling and running the program
创建 CMakeLists.txt 文件,复制下面内容到该文件(文件和)。

cmake_minimum_required(VERSION 2.8 FATAL_ERROR)project(moment_of_inertia)find_package(PCL 1.8 REQUIRED)include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})add_executable (moment_of_inertia moment_of_inertia.cpp)
target_link_libraries (moment_of_inertia ${PCL_LIBRARIES})

通常在build文件夹下,执行下面命令:

$ ./moment_of_inertia lamppost.pcd

PCL包围盒(详细介绍)相关推荐

  1. 【目标检测】56、目标检测超详细介绍 | Anchor-free/Anchor-based/Backbone/Neck/Label-Assignment/NMS/数据增强

    文章目录 1.双阶段和单阶段目标检测器 1.1 双阶段目标检测器 1.1.1 R-CNN 1.1.2 SPP 1.1.3 Fast R-CNN 1.1.4 Faster R-CNN 1.2 单阶段目标 ...

  2. HTML页面加载和解析流程详细介绍

    浏览器加载和渲染html的顺序.如何加快HTML页面加载速度.HTML页面加载和解析流程等等,在本文将为大家详细介绍下,感兴趣的朋友不要错过 浏览器加载和渲染html的顺序 1. IE下载的顺序是从上 ...

  3. mysql为什么要压测_mysql集群压测的详细介绍

    本篇文章给大家带来的内容是关于mysql集群压测的详细介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. mysql压测 mysql自带就有一个叫mysqlslap的压力测试工具,通 ...

  4. php比较运算符案列,PHP实例:PHP比较运算符的详细介绍

    <PHP实例:PHP比较运算符的详细介绍>要点: 本文介绍了PHP实例:PHP比较运算符的详细介绍,希望对您有用.如果有疑问,可以联系我们. 比拟运算符种类 PHP实战如同它们名称所暗示的 ...

  5. Tempdb数据库详细介绍

    Tempdb数据库详细介绍 一.Tempdb简介 tempdb是SQLServer的系统数据库一直都是SQLServer的重要组成部分,用来存储临时对象.可以简单理解tempdb是SQLServer的 ...

  6. linux路由介绍,Linux的路由表详细介绍

    Linux的路由表详细介绍 一 在Linux下执行route命令[root@localhost backup]# route -nKernel IP routing tableDestination ...

  7. pythonexcel介绍_Python 中pandas.read_excel详细介绍

    Python 中pandas.read_excel详细介绍 #coding:utf-8 import pandas as pd import numpy as np filefullpath = r& ...

  8. 渡神纪帧数测试软件,渡神纪芬尼斯崛起配置要求高吗 渡神纪配置要求详细介绍_游侠网...

    渡神纪芬尼斯崛起配置要求高吗?本作将在12月3日登陆主机和PC,很多玩家比较关心游戏的配置,这里给大家带来了渡神纪配置要求详细介绍,快来了解下吧. 渡神纪配置要求详细介绍 最低要求(720p/30 f ...

  9. C++11 unordered_map详细介绍

    整理的算法模板合集: ACM模板 目录: 1.介绍 1.1 特性 2. 模版 2.1 迭代器 3. 功能函数 3.1 构造函数 3.2 容量操作 3.2.1 size 3.2.2 empty 3.3 ...

  10. autosar中com模块_详细介绍AUTOSAR各个模块作用PART1(OS,SYS)

    这片文章中我们详细讲解下每个模块的功能,上图是vector的autosar方案,每个模块的详细介绍后续会有单独文章进行讲解,请关注.以下是各个模块的简介 1.VHSM hardware Securit ...

最新文章

  1. Microbiome:所谓的“富集培养”获得的微生物真的都是被“富集”出来的吗?
  2. 网络yum网址:http://mirrors.163.com/.help/
  3. UWP_小说在线阅读器:功能要求与技术要求
  4. yii2 mysql update_yii2 + mysql 常用增删改查操作语法以及事务
  5. 用C++访问SQL Server 2000的实例
  6. Blackcat主题-Wordpress
  7. bool c语言_C语言面试54题
  8. linux内核字符驱动设备,Linux学习笔记——linux内核字符设备驱动-Go语言中文社区...
  9. javascript图片库威力增强版
  10. 【比赛】智源-知乎联合发布大规模用户邀请回答数据集,同步开启10万元竞赛...
  11. 【简报】帮助开发人员在线了解CSS Filter特性的工具 - CSS FilterLab
  12. 十二款世界顶级杀毒软件下载---有序列号全可免费升级
  13. dpkg安装软件流程_Linux下安装软件的一般步骤
  14. 7-5 统计素数并求和
  15. The Little Schemer Fourth Edition,笔记01
  16. RxSwift学习(四)--- RxSwift 高阶函数
  17. 小议车辆环境视觉基础前视感知
  18. java 课设 商品库存管理系统
  19. 【组图】世界著名城市夜景
  20. 2018-8-28-win10-uwp-MVVM入门

热门文章

  1. Blender学习笔记:齿轮模型建立
  2. MTK Android GT928触摸屏驱动客制化触摸的开关
  3. java b2b2c 多商户 电商 源码,整套可运行
  4. dwg如何转换成pdf?
  5. 围棋智能机器人阿法狗,阿尔法狗机器人围棋
  6. 计算机主板设置语言,技嘉主板bios设置中文对照的方法步骤
  7. 怎么解决mysql登录闪退问题
  8. 电子合同助力企业实现全程无纸化闭环
  9. steam网络相关问题-社区错误代码118/无法自动登陆/短期内来自您网络的失败登录过多/无法连接至steam网络(2021/2/18更新)
  10. 空间中常见曲面图形的绘制(matlab)