本文主要是介绍【译】PCL官网教程翻译(20):惯性矩和偏心距描述符 - Moment of inertia and eccentricity based descriptors,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
英文原网页查看。
基于惯性矩和偏心距的描述符
在本教程中,我们将学习如何使用pcl::MomentOfInertiaEstimation类来获得基于偏心量和惯性矩的描述符。这个类还允许提取轴对齐和有向的点云包围框。但是请记住,提取的OBB可能并不是最小的边界框。
理论基础
特征提取方法的思想如下。首先计算点云的协方差矩阵,提取点云的特征值和特征向量。可以考虑得到的特征向量是归一化的,并且总是基于右手坐标系(主特征向量表示x轴,副特征向量表示z轴)。下一步是迭代过程。在每次迭代中旋转主特征向量。旋转顺序总是相同的,并且是围绕其他特征向量执行的,这就提供了点云旋转的不变性。从此,我们将把这个旋转的主矢量称为当前轴。
对每一当前轴的转动惯量进行计算。此外,当前轴也用于偏心计算。因此,将当前矢量作为平面的法向量,并将输入云投影到其上。然后计算得到的投影偏心量。
实现的类还提供了获取AABB和OBB的方法。沿着特征向量,将有向包围盒计算为AABB。
实现代码
首先,本教程需要点云。这是截屏上显示的。接下来你需要做的是在任何你喜欢的编辑器中创建一个文件moment_of_inertia.cpp,并在其中复制以下代码:
#include <vector>
#include <thread>#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>using namespace std::chrono_literals;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);feature_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::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);pcl::visualization::PCLVisualizer::Ptr viewer (new pcl::visualization::PCLVisualizer ("3D Viewer"));viewer->setBackgroundColor (0, 0, 0);viewer->addCoordinateSystem (1.0);viewer->initCameraParameters ();viewer->addPointCloud<pcl::PointXYZ> (cloud, "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, 1.0, 0.0, "AABB");viewer->setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_REPRESENTATION, pcl::visualization::PCL_VISUALIZER_REPRESENTATION_WIREFRAME, "AABB");Eigen::Vector3f position (position_OBB.x, position_OBB.y, position_OBB.z);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_REPRESENTATION, pcl::visualization::PCL_VISUALIZER_REPRESENTATION_WIREFRAME, "OBB");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");while(!viewer->wasStopped()){viewer->spinOnce (100);std::this_thread::sleep_for(100ms);}return (0);
}
解释
现在让我们研究一下这段代码的目的。头几行将被省略,因为它们很明显。
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ> ());if (pcl::io::loadPCDFile (argv[1], *cloud) == -1)return (-1);
这些行只是从.pcd文件加载点云。
pcl::MomentOfInertiaEstimation <pcl::PointXYZ> feature_extractor;feature_extractor.setInputCloud (cloud);feature_extractor.compute ();
下面是pcl:: momentofinertiaestimate类实例化的地方。之后,我们立即设置输入点云并启动计算过程,就这么简单。
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::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);
这些行显示了如何访问计算过的描述符和其他特性。
pcl::visualization::PCLVisualizer::Ptr viewer (new pcl::visualization::PCLVisualizer ("3D Viewer"));viewer->setBackgroundColor (0, 0, 0);viewer->addCoordinateSystem (1.0);viewer->initCameraParameters ();viewer->addPointCloud<pcl::PointXYZ> (cloud, "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, 1.0, 0.0, "AABB");viewer->setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_REPRESENTATION, pcl::visualization::PCL_VISUALIZER_REPRESENTATION_WIREFRAME, "AABB");
这些行简单地创建了用于结果可视化的PCLVisualizer类的实例。在这里,我们还添加了点云和AABB以实现可视化。我们设置了呈现属性,以便使用线框显示立方体,因为默认情况下使用的是实体立方体。
Eigen::Vector3f position (position_OBB.x, position_OBB.y, position_OBB.z);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_REPRESENTATION, pcl::visualization::PCL_VISUALIZER_REPRESENTATION_WIREFRAME, "OBB");
OBB的可视化稍微复杂一些。这里我们从旋转矩阵中创建一个四元数,设置OBBs的位置并将其传递给可视化器。
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");
这些代码负责特征向量的可视化。剩下的几行代码只是启动可视化过程。
编译和运行程序
在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})
完成可执行文件后,就可以运行它了,只需做:
$ ./moment_of_inertia lamppost.pcd
您应该会看到类似于此图像的内容。这里AABB是黄色的,OBB是红色的。你也可以看到特征向量。
这篇关于【译】PCL官网教程翻译(20):惯性矩和偏心距描述符 - Moment of inertia and eccentricity based descriptors的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!