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

问题描述

我正在研究我的硕士论文,以模拟来自Lidar-Data的半球照片。因此,我的主要目标是将笛卡尔坐标系中的3D点(X,Y,Z)投影到立体投影中(请参见图1,here)。我的Pointcloud的坐标系进行了转换,以使中心点位于(0,0),并且所有z值均为正。

enter image description here

我正在RStudio中进行编码,我首先尝试使用wikipedia中列出的笛卡尔坐标到球形坐标的公式来实现Pointcloud的球形投影。

r     <- sqrt(x^2 + y^2  + z^2)
theta <- acos(z/r)
phi   <- atan2(y,x)

我还尝试使用RPackage实用程序中的cart2sph函数来执行此操作,该功能应该也是如此。但是不幸的是,这两种方法的结果看起来都不像我想要的那样。这些点不适合在平面半球上,而似乎沿z轴定向(参见图2)。

enter image description here

有没有人建议如何在RStudio中实现Lidar Pointcloud的立体投影?甚至有一个带有某些功能的软件包都可以进行坐标转换吗?不幸的是,我没有太多的编码经验,我将非常感谢您提供的所有帮助。

修改

我使用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,rep(seq(-10,2))
z <- rep(3,84)

我们可以尝试在rgl中显示它,并添加一个红点以指示相机位置:

library(rgl)

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

enter image description here

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

projection <- function(x,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,z)
}

现在,当我们这样做时:

df <- projection(x,z)

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

plot3d(df$x,df$y,df$z,pi))

从下面查看

enter image description here

从侧面查看

enter image description here

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...