pcl中MomentOfInertiaEstimation解析与实例

news/2024/12/28 9:40:19/

pcl中features模块又基于惯性矩和偏心率的描述子,也可以求取点云的AABB和OBB包围盒,在计算的过程中法线一些问题,特此记录。
针对惯性矩和偏心率这两个数据的应用场景还不明确,因此暂时不做讨论,主要讨论求取OBB时的代码。

template <typename PointT> void
pcl::MomentOfInertiaEstimation<PointT>::computeOBB ()
{obb_min_point_.x = std::numeric_limits <float>::max ();obb_min_point_.y = std::numeric_limits <float>::max ();obb_min_point_.z = std::numeric_limits <float>::max ();obb_max_point_.x = std::numeric_limits <float>::min ();obb_max_point_.y = std::numeric_limits <float>::min ();obb_max_point_.z = std::numeric_limits <float>::min ();unsigned int number_of_points = static_cast <unsigned int> (indices_->size ());for (unsigned int i_point = 0; i_point < number_of_points; i_point++){float x = (input_->points[(*indices_)[i_point]].x - mean_value_ (0)) * major_axis_ (0) +(input_->points[(*indices_)[i_point]].y - mean_value_ (1)) * major_axis_ (1) +(input_->points[(*indices_)[i_point]].z - mean_value_ (2)) * major_axis_ (2);float y = (input_->points[(*indices_)[i_point]].x - mean_value_ (0)) * middle_axis_ (0) +(input_->points[(*indices_)[i_point]].y - mean_value_ (1)) * middle_axis_ (1) +(input_->points[(*indices_)[i_point]].z - mean_value_ (2)) * middle_axis_ (2);float z = (input_->points[(*indices_)[i_point]].x - mean_value_ (0)) * minor_axis_ (0) +(input_->points[(*indices_)[i_point]].y - mean_value_ (1)) * minor_axis_ (1) +(input_->points[(*indices_)[i_point]].z - mean_value_ (2)) * minor_axis_ (2);if (x <= obb_min_point_.x) obb_min_point_.x = x;if (y <= obb_min_point_.y) obb_min_point_.y = y;if (z <= obb_min_point_.z) obb_min_point_.z = z;if (x >= obb_max_point_.x) obb_max_point_.x = x;if (y >= obb_max_point_.y) obb_max_point_.y = y;if (z >= obb_max_point_.z) obb_max_point_.z = z;}obb_rotational_matrix_ << major_axis_ (0), middle_axis_ (0), minor_axis_ (0),major_axis_ (1), middle_axis_ (1), minor_axis_ (1),major_axis_ (2), middle_axis_ (2), minor_axis_ (2);Eigen::Vector3f shift ((obb_max_point_.x + obb_min_point_.x) / 2.0f,(obb_max_point_.y + obb_min_point_.y) / 2.0f,(obb_max_point_.z + obb_min_point_.z) / 2.0f);obb_min_point_.x -= shift (0);obb_min_point_.y -= shift (1);obb_min_point_.z -= shift (2);obb_max_point_.x -= shift (0);obb_max_point_.y -= shift (1);obb_max_point_.z -= shift (2);obb_position_ = mean_value_ + obb_rotational_matrix_ * shift;
}

如上所示,OBB求取的过程就是将点云转换到以中心为坐标原点,PCA计算的三个特征向量为轴方向的局部坐标系中,然后求取相应的AABB包围盒的过程,但是在文中最后一段

  Eigen::Vector3f shift ((obb_max_point_.x + obb_min_point_.x) / 2.0f,(obb_max_point_.y + obb_min_point_.y) / 2.0f,(obb_max_point_.z + obb_min_point_.z) / 2.0f);obb_min_point_.x -= shift (0);obb_min_point_.y -= shift (1);obb_min_point_.z -= shift (2);obb_max_point_.x -= shift (0);obb_max_point_.y -= shift (1);obb_max_point_.z -= shift (2);obb_position_ = mean_value_ + obb_rotational_matrix_ * shift;

第一点:
shift是包围盒的在局部坐标系中的中心坐标,
obb_rotational_matrix_ 是将局部坐标系转为全局坐标的旋转矩阵,平移矩阵就是中心点坐标。
obb_position_ 就是OBB包围盒中心的全局坐标

注意:这里局部坐标系和全局坐标系的转换关系要注意,对点云计算协方差阵,得到的特征向量矩阵是列向量组成的,obb_rotational_matrix_ 就是列向量组成的;
分析:
全局坐标->局部坐标
RP=Pt,此时的R是特征向量作为行向量组成的,这与得到的特征向量矩阵是转置的关系
局部坐标->全局坐标
RtPt=P,此时Rt是R的逆,这才是正确的,但是由于R的转置*R=单位阵,因此使用转置取代求逆操作,也就是说,此时的Rt是特征向量作为列组成的。所以出现
obb_position_ = mean_value_ + obb_rotational_matrix_ * shift;
obb_position_ 就是OBB包围盒中心的全局坐标。

第二点:

  obb_min_point_.x -= shift (0);obb_min_point_.y -= shift (1);obb_min_point_.z -= shift (2);obb_max_point_.x -= shift (0);obb_max_point_.y -= shift (1);obb_max_point_.z -= shift (2);

obb_min_point_和obb_max_point_减去包围盒中心点坐标是什么意思?
经过测试发现,减去中心点坐标之后,包围盒的坐标是存在问题的
在这里插入图片描述

如上图所示,两个黑色框中的点就是获取的包围盒的最小点和最大点,这里明显可以看出,这两点和显示的OBB包围盒没有关系,是有问题的。
因此绘制正确的OBB包围盒时,采用的是给定包围盒中心的坐标和包围盒的宽度和长度的方法进行绘制。
欢迎留言。


http://www.ppmy.cn/news/614.html

相关文章

C语言详细知识点(下)

⛄️上一篇⛄️C语言详细知识点&#xff08;上&#xff09; 文章目录五、数组1、一维数组的定义及使用2、二维数组的定义及使用3、字符数组的定义及使用六、函数1、函数的定义2、函数的调用3、函数的声明4、函数的嵌套调用5、函数的递归调用七、指针1、什么是指针2、指针变量3、…

借助cubeMX实现STM32MP157A(-M4核)UART、按键中断、环境检测开关实验

main.c 可以添加一句打印提示 int main(void) {/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init(…

在 Python 中构建一体化音频分析工具包,在一个地方分析您的音频文件

语言构成了人类之间每次对话的基础。因此,自然语言处理(或简称 NLP)领域无疑在帮助人类日常生活方面具有巨大潜力。 简而言之,NLP 领域包含一组旨在理解人类语言数据并完成下游任务的技术。 NLP 技术涵盖许多领域,例如问答 (QA)、命名实体识别 (NER)、文本摘要、自然语言…

网站变灰代码如何让网页变灰

1.网站变灰代码应用场景 一般在清明节&#xff0c;全国哀悼日&#xff0c;大地震的日子&#xff0c;以及一些影响力很大的伟人逝世或纪念日的时候&#xff0c;身为站长的我们都会让自己的网站的全部网页变成灰色&#xff08;黑白色&#xff09;&#xff0c;以表示我们对逝者的…

【Confluence】使用start-confluence.sh命令重启后提示找不到网页HTTP404

问题&#xff1a; 1、使用start-confluence.sh命令启动Confluence&#xff0c;提示成功 2、浏览器访问Confluence出现“找不到网页” HTTP 404错误 解决方案&#xff1a; 1、ps -ef|grep java 查看进程 2、发现有以下类似信息&#xff0c;说明Tomcat没有关闭 Djava.util.logg…

Pytorch的入门操作(三)

2.7 使用Pytorch实现手写数字识别 2.7.1 目标 知道如何使用Pytorch完成神经网络的构建知道Pytorch中激活函数的使用方法知道Pytorch中torchvision.transforms 中常见图形处理函数的使用知道如何训练模型和如何评估模型 2.7.2 思路和流程分析 流程: 准备数据&#xff0c;这…

猿创征文|2022年前端之路——我的前端开发好帮手

&#x1f525;活动回顾 文章评审将由 CSDN 技术编辑以及特邀专家两位评委联合打分&#xff0c;最终取平均值&#xff0c;前 25 名为入围稿件&#xff0c;获得奖励。相同得分情况下&#xff0c;阅读量较高的文章排名靠前。经过激烈的评选&#xff0c;本人的文章有幸成为TOP5的优…

mac下安装nodejs跟vscode

1.打开官网 Node.js 2.点击下载 3.下载完成&#xff0c;根据提示下一步安装&#xff0c;安装完成后&#xff0c;在vscode中新建一个js文件&#xff0c;执行node test.js