与xyz坐标的3d表面图

时间:2014-03-25 09:26:54

标签: r plot 3d rgl qhull

我希望有经验的人可以帮助我们如何从xyz数据中准备形状文件。虽然没有提供创建here的前面步骤,但可以看到彗星Churyumov-Gerasimenko的精心准备的数据集的一个很好的例子shape file

我试图更好地了解如何将曲面应用于给定的XYZ坐标集。使用笛卡尔坐标直接使用R包" rgl"但是环绕的形状看起来更难。我找到了R包geometry,它提供了QHULL函数的接口。我尝试使用它来计算Delaunay三角剖面,然后我可以在rgl中绘制。我无法弄清楚与函数delaunayn相关的一些选项,以便可能控制计算这些方面的最大距离。我希望这里有人可能对xyz数据改进表面结构有一些想法。

使用" Stanford bunnny"数据集:

library(onion)
library(rgl)
library(geometry)
data(bunny)

#XYZ point plot
open3d()
points3d(bunny, col=8, size=0.1)
#rgl.snapshot("3d_bunny_points.png")

#Facets following Delaunay triangulation
tc.bunny <- delaunayn(bunny)
open3d()
tetramesh(tc.bunny, bunny, alpha=0.25, col=8)
#rgl.snapshot("3d_bunny_facets.png")

enter image description here

This answer让我相信Qhull的R实现可能存在问题。此外,我现在尝试了各种设置(例如delaunayn(bunny, options="Qt")),效果甚微。 Qhull选项概述为here

编辑:

这是一个额外的(更简单的)球体示例。即使在这里,小平面的计算并不总能找到最近的相邻顶点(如果你旋转球,你会看到一些小平面穿过内部)。

library(rgl)
library(geometry)
set.seed(1)
n <- 10
rho <- 1
theta <- seq(0, 2*pi,, n) # azimuthal coordinate running from 0 to 2*pi 
phi <- seq(0, pi,, n) # polar coordinate running from 0 to pi (colatitude)
grd <- expand.grid(theta=theta, phi=phi)

x <- rho * cos(grd$theta) * sin(grd$phi)
y <- rho * sin(grd$theta) * sin(grd$phi)
z <- rho * cos(grd$phi)

set.seed(1)
xyz <- cbind(x,y,z)
tbr = t(surf.tri(xyz, delaunayn(xyz)))
open3d()
rgl.triangles(xyz[tbr,1], xyz[tbr,2], xyz[tbr,3], col = 5, alpha=0.5)
rgl.snapshot("ball.png")

enter image description here

3 个答案:

答案 0 :(得分:18)

这是一种使用核密度估计和contour3d的{​​{1}}函数的方法。我一直玩,直到找到misc3d的值得体面的值。它不是非常精确,但您可以调整一些东西以获得更好,更准确的表面。如果你的内存超过8GB,那么你可以将levels增加到超出我在此处所做的范围。

n

enter image description here enter image description here

右侧的图像位于底部,只是为了显示另一个视图。

您可以在library(rgl) library(misc3d) library(onion); data(bunny) # the larger the n, the longer it takes, the more RAM you need bunny.dens <- kde3d(bunny[,1],bunny[,2],bunny[,3], n=150, lims=c(-.1,.2,-.1,.2,-.1,.2)) # I chose lim values manually contour3d(bunny.dens$d, level = 600, color = "pink", color2 = "green", smooth=500) rgl.viewpoint(zoom=.75) 中为n使用更大的值,但这会花费更长时间,如果数组太大,您可能会耗尽RAM。您还可以尝试不同的带宽(此处默认使用)。我从Computing and Displaying Isosurfaces in R - Feng & Tierney 2008采用了这种方法。

使用kde3d包非常相似的isosurface方法:

Rvcg

enter image description here

由于它是基于密度估计的方法,我们可以通过增加兔子的密度来获得更多。我也在这里使用library(Rvcg) library(rgl) library(misc3d) library(onion); data(bunny) bunny.dens <- kde3d(bunny[,1],bunny[,2],bunny[,3], n=150, lims=c(-.1,.2,-.1,.2,-.1,.2)) # I chose lim values manually bunny.mesh <- vcgIsosurface(bunny.dens$d, threshold=600) shade3d(vcgSmooth(bunny.mesh,"HC",iteration=3),col="pink") # do a little smoothing 。成本是计算时间的显着增加,但结果表面更好野兔

n=400

enter image description here

存在更好,更有效的表面重建方法(例如,动力外壳,泊松表面重建,球转动算法),但我不知道在R中已经实现了任何方法。

这是一个相关的Stack Overflow帖子,其中包含一些很棒的信息和检查链接(包括代码链接):robust algorithm for surface reconstruction from 3D point cloud?

答案 1 :(得分:13)

我认为使用alphashape3d包找到了一种可能的解决方案。我必须玩一下才能获得alpha的可接受值,这与给定数据集中的距离有关(例如sd的{​​{1}}给了我一些见解)。我仍在试图弄清楚如何更好地控制顶点和边缘中的线条宽度,以免占主导地位,但这可能与bunny中的设置有关。

实施例

rgl

enter image description here

编辑:

只有通过调整library(onion) library(rgl) library(geometry) library(alphashape3d) data(bunny) apply(bunny,2,sd) alphabunny <- ashape3d(bunny, alpha = 0.003) bg3d(1) plot.ashape3d(alphabunny, col=c(5,5,5), lwd=0.001, size=0, transparency=rep(0.5,3), indexAlpha = "all") 函数,才能删除边和顶点:​​

plot.ashape3d

enter image description here

答案 2 :(得分:3)

2016年7月将包Rvcg更新为版本0.14,并添加了球旋转曲面重建。该函数为vcgBallPivoting

library(Rvcg) # needs to be >= version 0.14
library(rgl)
library(onion); data(bunny)

# default parameters
bunnybp <- vcgBallPivoting(bunny, radius = 0.0022, clustering = 0.2, angle = pi/2)
shade3d(bunnybp, col = rainbow(1000), specular = "black")
shade3d(bunnybp, col = "pink", specular = "black") # easier to see problem areas.

enter image description here enter image description here

球旋转和默认参数设置对于斯坦福兔子来说并不完美(正如评论radius = 0.0022中的乌贼44所指出的那样优于默认的radius = 0),你留下了一些空白在表面上。实际的兔子在基地有2个洞,一些扫描限制导致其他一些洞(如下所述:https://graphics.stanford.edu/software/scanview/models/bunny.html)。您可能能够找到更好的参数,并且使用vcgBallPivoting(我的机器上约0.5秒)非常快,但可能需要额外的努力/方法来缩小差距。