任意空间平面点云旋转投影至水平面—罗德里格旋转公式

1、背景介绍

将三维空间中位于任意平面上的点云数据,通过一系列的坐标变换(平移+旋转),使其投影到XOY平面上,同时保证点云的几何中心与XOY平面的原点重合,同时点云形状保持不变。具体效果如下,具体来说,对于原始点集(红色点集),对其进行平移+旋转处理后,得到新的点云(白色点云),该点云与水平面平行,同时保持与原始点云形状相同。

|----------------------------------------------------------------------------|----------------------------------------------------------------------------|----------------------------------------------------------------------------|
| | | |
| 三维空间动图 | 前视图(白色点云水平) | 俯视图(两点云簇形状形同) |

为什么要将点云旋转,将其与水平面平行,这样做的好处体现在以下几方面:

  • 数据简化:将三维问题简化为二维问题,便于后续处理,如数据分析、可视化、特征提取等。
  • 算法适用性:某些算法可能在二维平面上表现得更好或更高效,投影可以使得这类算法得以应用。
  • 几何一致性:确保所有点云数据在同一参考平面上,便于比较和处理。

2、点云旋转投影流程与原理

2.1 流程介绍

一般来说,点云旋转投影至水平面,包括如下步骤:

  • 中心化点云:首先计算点云的几何中心,然后将点云相对于其几何中心平移,使中心点与全局坐标系的原点重合。
  • 确定平面法向量:找出点云所在平面的法向量,这是点云所在平面垂直于三维空间的方向。
  • 旋转对齐:根据平面法向量与Z轴的偏差,构造旋转矩阵,旋转点云使之与XOY平面平行或重合。目的是消除Z坐标的影响,使所有点落在XOY平面上。
  • 投影:完成旋转后,可以安全地忽略所有点的Z坐标,只保留X和Y坐标,从而将点云投影到XOY平面上。

上述四个步骤中,其实最为核心的步骤是求解旋转矩阵,本文介绍基于罗德里格旋转公式方法求解旋转矩阵。

2.2 推导过程

假设待旋转的点云集,其拟合平面对应的法向量为vectorBefore(x1,y1,z1),经过旋转处理后,最终要得到的平面法向量为 vectorAfter(x2,y2,z2),将这两个向量转为单位向量。

得到 va = normalize(vectorBefore), vb = normalize(vectorAfter)

② vs = vb × va, 叉乘得到旋转轴vs

③ v = normalize(vs), vs转为单位向量得到v

④ ca = vb · va, 点乘得到旋转角的余弦值 ca, 即cos(angle)

⑤ vt = v * scale, 对v进行缩放,方便后面计算, scale = 1 - ca

⑥ 旋转矩阵rm为 [3,3]矩阵, 计算原理为罗德里格旋转公式(Rodrigues' rotation formula)

rm[0,0] = vt.x * v.x + ca

rm[1,1] = vt.y * v.y + ca

rm[2,2] = vt.z * v.z + ca

vt.x *= v.y

vt.z *= v.x

vt.y *= v.z

rm[0,1] = vt.x - vs.z

rm[0,2] = vt.z - vs.y

rm[1,0] = vt.x - vs.z

rm[1,2] = vt.y - vs.x

rm[2,0] = vt.z - vs.y

rm[2,1] = vt.y - vs.x

3、测试与结果

基于上述步骤原理,使用C++进行编程,使用Eigen库进行向量点乘、叉乘。源代码下载链接:

https://download.csdn.net/download/qq_32867925/89552493

随机生成10000个位于同一平面点集,其中可以根据需要修改平面方程,从而生成不同平面上点集。

cpp 复制代码
for (int i = 0; i < numpt; i++)
	{
		double x = rand() % 500;
		double y = rand() % 500;
		double z = 1 * x + 1 * y - 5;//假设平面方程类型 x+y-z-5=0

		Vector3d temp(x, y, z);
		points.push_back(temp);
	}

不进行中心化处理进行旋转,即旋转中心随机,结果如下,平面方程为:x+y-z-5=0。其中,红色点集为原始点云,白色点集为旋转后点集。可以发现,白色点集均处于水平,即旋转成功,与水平面平行。通过解算参数也可以看出,z轴方向的法向量分量为-1,x轴、y轴分量为0。

|----------------------------------------------------------------------------|----------------------------------------------------------------------------|
| | |
| 未中心化旋转 | 前视图 |
| | |
| 中心化后旋转 | 前视图 |

4、总结

介绍了三维空间内平面点云旋转平移,投影至水平面过程,并展示程序测试效果。

相关推荐
新手小白勇闯新世界2 个月前
论文阅读(一种基于球面投影和特征提取的岩石点云快速配准算法)
论文阅读·点云·配准·icp·特征提取
Deepcong2 个月前
3D点云与2D图像的相互转换:2D图像对应像素的坐标 转为3D空间的对应坐标
c++·目标跟踪·点云·2d转3d
PHP代码2 个月前
entwine 和 conda环境下 使用和踩坑 详细步骤! 已解决
服务器·conda·点云
空名_Noname3 个月前
Open3D实现点云数据的序列化与网络传输
c++·点云·open3d
点云-激光雷达-Slam-三维牙齿5 个月前
单目测距 单目相机测距 图片像素坐标转实际坐标的一种转换方案
人工智能·python·算法·点云
点云-激光雷达-Slam-三维牙齿6 个月前
Open3d 点云投影到 xoy yoz 平面最简单的方式(附python 代码)
python·算法·平面·点云
coco_1998_26 个月前
Ubuntu22.04 搭建 PCL 环境(VTK源码安装),PCL测试代码
linux·vtk·点云·pcl
LiDAR点云7 个月前
PCL平面多边形可视化
点云·pcl·多边形可视化
信必诺7 个月前
VTK —— 二、教程七 - 对点云进行操作(按下r键切换选取或观察模式)(附完整源码)
c++·vtk·点云