平滑连续的2D点

4

更新

感谢 @user20650 和 @李哲源 Zheyuan Li,这是我想出的解决方案:

# Example data set: df
# 3600 observations/points
# Create a vector of the cumulative distances between all of the points
require(Momocs)
cumdist <- coo_perimcum(df)

# Apply splines parametrically - define a spline interpolated mapping R --> R^2 of some curve c
# c(t) = (x(t), y(t))
# 't' is the set of cumulative distances (as defined above)
# Set the number of points to some fraction of the number of observations in the data set (5% in this case)

splines <- cbind.data.frame(x = c(spline(cumdist, df[, 1], method = "natural",
                                         n = ceiling(nrow(df)*0.05))$y),
                            y = c(spline(cumdist, df[, 2], method = "natural",
                                         n = ceiling(nrow(df)*0.05))$y))

plot(df, col = "gray")
lines(splines, col = "red", lwd = 2)

distance <- function(df, mm) # data frame must be in the form (x,y); mm = pixel to mm conversion factor
{
  require(Momocs)
  cumdist <- coo_perimcum(df) # calculates the cumulative Euclidean distance between points
  splines <- cbind.data.frame(x = c(spline(cumdist, df[, 1], method = "natural",
                                           n = ceiling(nrow(df)*0.05))$y),
                              y = c(spline(cumdist, df[, 2], method = "natural",
                                           n = ceiling(nrow(df)*0.05))$y))
  assemble  <- Mod(diff(splines$x+1i*splines$y))*mm
  distance  <- sum(assemble)/1000 # sum the distances and convert to meters
  distance
}

distance(df, 0.444444)
distance(splines, 0.444444)

enter image description here

原始帖子

我正在尝试平滑动物足迹的崎岖路径,以便更准确地确定它们的长度。数据以(x,y)二维坐标的形式呈现。

我手头的示例数据集相当大(3600行),以更好地说明问题的范围。可在此处获取.Rdata文件:

https://osu.box.com/v/tracks

with(df, plot(x,y, type = "l"))

enter image description here

将smooth.spine()应用于整个数据集是不合适的,因为这些动物会蜿蜒曲折地移动(走圈等)。

enter image description here

接着,我有了一个想法:将数据分成较小的路径,并对每个列表元素应用smooth.spline()。最终目标是将列表重新整合成连续、平滑的轨迹。

chunks <- list(split(df, (as.numeric(rownames(df))-1) %/% 90))

smooth.tracks <- function(x)
{
  smooth.spline(x, spar = 0.55)
}

df.smooth <- lapply(chunks, smooth.tracks)

由于出现的错误:
Error in xy.coords(x, y) : 
  'x' is a list, but does not have components 'x' and 'y

我可能在这里漏掉了非常简单的东西... 有什么想法吗?


1
虽然不确定,但也许这个问题可以提供一个方向:https://dev59.com/h5Xfa4cB1Zd3GeqPktWv - user20650
1个回答

8

只需分别平滑x-coordy-coord。如果你有一条曲线y = y(x),你可以通过x = x(t), y = y(t)来表示它。

## load your data frame "df"
t <- 1:nrow(df)
x <- df$x
y <- df$y

sx <- smooth.spline(t, x, df = 50)
sy <- smooth.spline(t, y, df = 50)

plot(df, cex = 0.25, col = "gray")
lines(sx[[2]], sy[[2]], col = 2, lwd = 2)

enter image description here


如果数据框不太大,这个解决方案肯定有效。然而,我提供的示例数据框只有原始数据框的10%大小(3600行对比36000行)。即使在smooth.spline()中增加自由度,也会使循环超出原始路径范围。 - Tavaro Evanis
另外,是否有可能使样条点彼此等距? - Tavaro Evanis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接