PCL 获取点云AABB包围盒+OBB包围盒+特征值+特征向量等(Feature_MomentOfInertiaEstimation)

注意:本例是调用PCL自己的接口,直接计算 AABB包围盒 + OBB包围盒 + 特征值 + 特征向量 + 惯性矩 + 偏心率

使用该接口计算速度非常慢!!!工作中使用时,建议自己重写一次!!!

1.原理

(1)AABB包围盒(轴对齐包围盒):包围盒XYZ轴都与坐标轴对齐。AABB盒解释

(2)OBB包围盒(有向包围盒):包围盒XYZ轴都紧贴物体(比AABB包围盒描述物体更加的紧密)。OBB盒解释

(3)特征值和特征向量:在协方差矩阵那一块有讲解。特征值及特征向量解释

(4)惯性矩:不重要。惯性矩

(5)偏心率:不重要。偏心率

(6)质心:在点云场景中,一般被当做一块点云的中心点质心解释

2.使用场景

(1)测试用

(2)如果自己写的算法计算不正确,直接调PCL的,

但注意:首先做计算的点云数据量要小,其次,最好先进行一次体素抽稀(保持点云形态结构)/法向量下采样(保存点云边缘),以降低数据量。再做计算。

3.注意事项

速度很慢。

4.关键函数

(1)获取AABB盒

    pcl::PointXYZ aabbMin, aabbMax;                             // AABB盒最大xyz值,最小xyz值
    bool bAabb = feature.getAABB(aabbMin, aabbMax);             // 计算成功为true,否则为false

(2)获取OBB盒

    pcl::PointXYZ obbMin, obbMax, pos;                          // obb盒最大xyz值,最小xyz值,中心点位置
    Eigen::Matrix3f obbMat;                                     // obb盒的旋转矩阵
    bool bObb = feature.getOBB(obbMin, obbMax, pos, obbMat);    // 计算成功为true,否则为false

(3)获取特征值

    float majorValue, middleValue, minorValue;                                              // 三特征值:主要、中间、次要
    bool bEigenValue = feature.getEigenValues(majorValue, middleValue, minorValue);         // 计算成功为true,否则为false

(4)获取特征向量

    Eigen::Vector3f majorVector, middleVector, minorVector;                                 // 三特征向量:主要、中间、次要
    bool bEigenVector = feature.getEigenVectors(majorVector, middleVector, minorVector);    // 计算成功为true,否则为false

(5)获取惯性矩

    std::vector <float> momentOfInertia;                                                    // 计算惯性矩
    bool bMomentOfInertia = feature.getMomentOfInertia(momentOfInertia);                    // 计算成功为true,否则为false

(6)获取偏心度

    std::vector <float> eccentricity;                                                       // 计算偏心度
    bool bEccentricity = feature.getEccentricity(eccentricity);                             // 计算成功为true,否则为false

(7)获取质心

    Eigen::Vector3f mass_center;                                                            // 计算质心
    bool bMassCenter = feature.getMassCenter(mass_center);                                  // 计算成功为true,否则为false

5.代码

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/features/moment_of_inertia_estimation.h>
#include <pcl/features/moment_invariants.h>
#include <boost/thread/thread.hpp>
#include <pcl/visualization/pcl_visualizer.h>

int main()
{
    /***************通过惯性矩和偏心率计算AABB、OBB等一系列值********************/
    // 原始点云
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::io::loadPCDFile("D:/code/csdn/data/person4.pcd", *cloud_in);                             // 加载原始点云数据
    
    pcl::MomentOfInertiaEstimation<pcl::PointXYZ> feature;
    feature.setInputCloud(cloud_in);
    feature.compute();

    // 获取AABB盒
    pcl::PointXYZ aabbMin, aabbMax;                             // AABB盒最大xyz值,最小xyz值
    bool bAabb = feature.getAABB(aabbMin, aabbMax);             // 计算成功为true,否则为false
    
    // 获取OBB盒
    pcl::PointXYZ obbMin, obbMax, pos;                          // obb盒最大xyz值,最小xyz值,中心点位置
    Eigen::Matrix3f obbMat;                                     // obb盒的旋转矩阵
    bool bObb = feature.getOBB(obbMin, obbMax, pos, obbMat);    // 计算成功为true,否则为false

    // 获取特征值
    float majorValue, middleValue, minorValue;                                              // 三特征值:主要、中间、次要
    bool bEigenValue = feature.getEigenValues(majorValue, middleValue, minorValue);         // 计算成功为true,否则为false

    // 获取特征向量
    Eigen::Vector3f majorVector, middleVector, minorVector;                                 // 三特征向量:主要、中间、次要
    bool bEigenVector = feature.getEigenVectors(majorVector, middleVector, minorVector);    // 计算成功为true,否则为false

    // 获取惯性矩
    std::vector <float> momentOfInertia;                                                    // 计算惯性矩
    bool bMomentOfInertia = feature.getMomentOfInertia(momentOfInertia);                    // 计算成功为true,否则为false

    // 获取偏心度
    std::vector <float> eccentricity;                                                       // 计算偏心度
    bool bEccentricity = feature.getEccentricity(eccentricity);                             // 计算成功为true,否则为false

    // 获取质心
    Eigen::Vector3f mass_center;                                                            // 计算质心
    bool bMassCenter = feature.getMassCenter(mass_center);                                  // 计算成功为true,否则为false
    
    /****************打印********************/
    std::cout << "AABB盒:" << bAabb << std::endl;
    std::cout << "最小值:" << aabbMin << ";" << "最大值:" << aabbMax << ";" << std::endl;
    std::cout << " " << std::endl;
    std::cout << "OBB盒:" << bObb << std::endl;
    std::cout << "最小值:" << obbMin << ";" << "最大值:" << obbMax << ";" << "位置:" << pos << ";" << "旋转矩阵:" << obbMat << ";" << std::endl;
    std::cout << " " << std::endl;
    std::cout << "特征值:" << bEigenValue << std::endl;
    std::cout << "主要:" << majorValue << ";" << "中间:" << middleValue << ";" << "次要:" << minorValue << ";" << std::endl;
    std::cout << " " << std::endl;
    std::cout << "特征向量:" << bEigenVector << std::endl;
    std::cout << "主要:" << majorVector << ";" << "中间:" << middleVector << ";" << "次要:" << minorVector << ";" << std::endl;
    std::cout << " " << std::endl;
    std::cout << "质心:" << bMassCenter << std::endl;
    std::cout << "质心:" << mass_center << ";" << std::endl;

    /****************展示********************/
    // AABB点云
    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("AABB"));
    viewer->setBackgroundColor(1, 1, 1);
    viewer->addCoordinateSystem(1.0);
    viewer->addPointCloud<pcl::PointXYZ>(cloud_in, pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>(cloud_in, 0, 255, 0), "AABB");
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "AABB");
    // AABB盒
    viewer->addCube(aabbMin.x, aabbMax.x, aabbMin.y, aabbMax.y, aabbMin.z, aabbMax.z, 1.0, 0.0, 0.0, "AABB");
    viewer->setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_REPRESENTATION, pcl::visualization::PCL_VISUALIZER_REPRESENTATION_WIREFRAME, "AABB");

    // OBB点云
    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer1(new pcl::visualization::PCLVisualizer("OBBCloud"));
    viewer1->setBackgroundColor(1, 1, 1);
    viewer1->addCoordinateSystem(1.0);
    viewer1->addPointCloud<pcl::PointXYZ>(cloud_in, pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>(cloud_in, 0, 255, 0), "OBBCloud");
    viewer1->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "OBBCloud");
    // OBB盒子
    const Eigen::Vector3f translation(pos.x, pos.y, pos.z);
    const Eigen::Quaternionf rotation(obbMat);
    viewer1->addCube(translation, rotation, obbMax.x - obbMin.x , obbMax.y - obbMin.y, obbMax.z - obbMin.z, "OBB");
    viewer1->setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_REPRESENTATION, pcl::visualization::PCL_VISUALIZER_REPRESENTATION_WIREFRAME, "OBB");
    viewer1->setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 1.0, 0.0, 0.0, "OBB");
    while (!viewer->wasStopped() || !viewer1->wasStopped())
    {
        viewer->spinOnce(100);
        viewer1->spinOnce(100);
        boost::this_thread::sleep(boost::posix_time::microseconds(100000));
    }

    return (0);
}

6.结果展示

(1)计算得到的各项值

(2)AABB包围盒

(3)OBB包围盒

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值