将 3D 激光雷达点从笛卡尔坐标系转换为球坐标系和立体投影

Transform 3D Lidar-Points from cartesian coordinate-system to spherical coordinate-system and a stereographic projection

我正在研究我的硕士论文,以模拟来自 Lidar-Data 的半球形照片。所以我的主要目标是将笛卡尔坐标系中的 3D 点 (X,Y,Z) 投影到立体投影(见图 1,来自:here)。我的 Pointcloud 的坐标系经过变换,中心点位于 (0,0,0) 并且所有 z 值都是正数。

我在 RStudio 中编码,我首先尝试使用 wikipedia.

中列出的笛卡尔到球坐标的公式来实现点云的球投影
r     <- sqrt(x^2 + y^2  + z^2)
theta <- acos(z/r)
phi   <- atan2(y,x)

我也尝试使用 RPackage pracma 中的 cart2sph-function 来完成它,它应该做同样的事情。但不幸的是,这两种方法的结果看起来都不像我想要的那样。这些点不适合平面半球,但似乎只是沿着 z 轴定向(见图 2)。

有没有人建议如何在RStudio中实现激光雷达点云的立体投影?甚至可能有一个包含一些功能的包来进行坐标转换?不幸的是,我没有太多编码经验,我将非常感谢您的帮助。

编辑

我使用 Allans 脚本绘制半球上的笛卡尔点。使用软件 Cloudcompare 结果看起来像这样:

图片: Hemisphere

我还用变换后的笛卡尔坐标做了立体投影:

x2 <- (x / (1 + z))
y2 <- (y / (1 + z))
project_2d <- data.frame(x2, y2)

图片: Stereographic projection

我仍然想知道为什么地块的外边缘不适合一个完美的圆圈,因为所有树干都具有相同的 min(z) 值(我使用了剪裁框)。所以所有的树干都应该在半球的“赤道”上排成一行。你有什么线索吗?

这个结果很难用3D显示出来,但我会尽力的。

假设我们有一组点,呈十字形悬挂在相机上方,与地面平行:

x <- c(rep(seq(-10, 10, 1), 2), rep(-1, 21), rep(1, 21))
y <- c(rep(-1, 21), rep(1, 21), rep(seq(-10, 10, 1), 2))
z <- rep(3, 84)

我们可以尝试在rgl中展示这一点,添加一个红点来指示相机位置:

library(rgl)

plot3d(x, y, z, zlim = c(0, 10))
points3d(0, 0, 0, col = "red")

使用您找到的球形变换公式 co-ordinates 我们可以将这些 3D 点从 x、y、z 转换为 theta、phi 和 r。但是,要将它们投影到笛卡尔 co-ordinates 中的半球上,我们需要让 r 与相机保持固定距离。然后,我们需要根据 theta、phi 和固定 r 计算该半球上各点的 x、y、z co-ordinates。这个函数应该这样做:

projection <- function(x, y, z) {
  r     <- sqrt(x^2 + y^2  + z^2)
  theta <- acos(z / r)
  phi   <- atan2(y, x)
  y <- theta * cos(phi)
  x <- theta * sin(phi)
  z <- sqrt((pi / 2)^2 - x^2 - y^2)
  data.frame(x, y, z)
}

所以现在当我们这样做时:

df <- projection(x, y, z)

我们可以再次绘制以显示投影到半球上的点:

plot3d(df$x, df$y, df$z, zlim = c(0, pi))

俯视图

侧视图