PCL包围盒计算原理及代码

 1.计算最小包围盒OBB原理

Physics - 高级碰撞检测技术__Max-CSDN博客

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

最小包围盒顶点计算的过程大致如下:
1.输入点云转换至远点后,求得变换后点云的最大最小x,y,z轴的坐标,此时(max.x,max.y,max.z),(max.x,min.y,max.z),(max.x,max.y,min.z),(min.x,max.y,max.z),(min.x,max.y,min.z),(min.x,min.y,max.z),(min.x,min.y,max.z),(min.x,min.y,min.z)
即为变换后点云的包围盒,也是原始输入点云包围盒顶点坐标经过变化后的坐标.
2.将上述求得的8个包围盒坐标逆变换回输入点云的坐标系,即得到原始输入点云的包围盒顶点坐标.

为什么要将点云变换到原点,而不是直接对原点云进行操作?
如果只求原点云的主方向,则直接对原点云进行操作就可以了。之所以要将点云转换到原点,是为了后续能够正确的显示包围盒。原因在于getMinMax3D()计算得到的min_pt与max_pt代表的是原点坐标系下的边界值,而不是点云主方向坐标系下的值。

 

PCL_PCA-最小包围盒(画出最小包围盒顶点) - CodeAntenna

简化版:

PCA(主成分分析)获取BoundingBox&代码分析_青箬笠,绿蓑衣-CSDN博客_whd分别代表长宽高

[算法][包围盒]球,AABB,OBB - 南水之源 - 博客园

SVD 计算 OBB 包围盒,和OBB 包围盒坐标变换原理

S03E11: 用 SVD 分解创建点云的 OBB 包围盒 - 掘金

2. PCA主元分析法

A tutorial on Principal Components Analysis | 主成分分析(PCA)教程 - houchaoqun - 博客园

3.小包围盒合并

 根据包围盒斜边长,将小包围盒放到容器里面,大包围盒放到另一个容器里面,循环遍历计算小包围盒和大包围盒之间的中心距,找到最小中心距,提取小包围盒与大包围盒最小点、最大点合并成包含小包围盒的大包围盒。或者是小包围盒中心点的k-d tree 树的快速邻域搜索大包围盒中心点,根据存储近邻点对应平方距离的vector排序找到最小值,即最小中心距,提取小包围盒与大包围盒最小点、最大点合并成包含小包围盒的大包围盒。

    int s[] = {1,3,2,7,5};
    vector<int> vec(s, s+5);
    //正向排序 即按照从小到大的顺序排序
    sort(vec.begin(), vec.end());
    for(vector<int>::iterator it=vec.begin(); it!=vec.end(); it++){
        cout<<*it<<" ";
    }
    cout<<endl;

    //逆向排序 即按照从大到小的顺序进行排序
    sort(vec.rbegin(), vec.rend());
    for(vector<int>::iterator it=vec.begin(); it!=vec.end(); it++){
        cout<<*it<<" ";
    }
    cout<<endl;

  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PCL(点云库)提供了计算点云包围的函数,可以方便地计算点云的边界框和轴对齐的边界框。下面是一个使用PCL计算点云包围的示例代码: ```cpp #include <iostream> #include <pcl/point_types.h> #include <pcl/features/moment_of_inertia_estimation.h> int main() { // 生成一个简单的点云数据 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); cloud->width = 5; cloud->height = 1; cloud->points.resize(cloud->width * cloud->height); for (std::size_t i = 0; i < cloud->points.size(); ++i) { cloud->points[i].x = rand() / (RAND_MAX + 1.0); cloud->points[i].y = rand() / (RAND_MAX + 1.0); cloud->points[i].z = rand() / (RAND_MAX + 1.0); } // 计算点云的包围 pcl::MomentOfInertiaEstimation<pcl::PointXYZ> feature_extractor; feature_extractor.setInputCloud(cloud); feature_extractor.compute(); // 获取点云包围的中心和尺寸 pcl::PointXYZ min_point, max_point, pos, rot_axis; Eigen::Matrix3f rot_mat; feature_extractor.getAABB(min_point, max_point); feature_extractor.getOBB(pos, rot_mat, rot_axis, min_point, max_point); // 打印点云包围的中心和尺寸 std::cout << "AABB min point: " << min_point << std::endl; std::cout << "AABB max point: " << max_point << std::endl; std::cout << "OBB center: " << pos << std::endl; std::cout << "OBB size: " << max_point - min_point << std::endl; return 0; } ``` 在这个示例中,我们使用PCL生成了一个简单的点云数据,并使用MomentOfInertiaEstimation类计算了点云的包围。通过调用getAABB和getOBB函数,我们可以获取点云包围的中心和尺寸。其中,AABB表示轴对齐的边界框,OBB表示任意方向的边界框。最后,我们将点云包围的中心和尺寸打印出来。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值