简体   繁体   English

平滑连续2D点

[英]Smoothing Continuous 2D Points

UPDATE UPDATE

Thanks to @user20650 and @李哲源 Zheyuan Li, here is the solution I came up with: 感谢@ 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)

在此处输入图片说明

ORIGINAL POST 原始邮件

I am attempting to smooth the jagged paths of animal tracks to determine their lengths with greater accuracy. 我正在尝试平滑动物轨迹的锯齿状路径,以更精确地确定它们的长度。 The data is in the form of (x,y) 2D coordinates. 数据采用(x,y)2D坐标的形式。

The example data set I have is rather large (3600 rows) to better illustrate the scope of the problem. 我拥有的示例数据集相当大(3600行),可以更好地说明问题的范围。 It is available as an .Rdata file here: 它可以通过.Rdata文件在此处获得:

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

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

在此处输入图片说明

Applying smooth.spine() to the entire data set was inappropriate as these animals meander quite a lot (walking in loops and such). 对所有数据集应用smooth.spine()是不合适的,因为这些动物会蜿蜒很多(循环行走等)。

在此处输入图片说明

Then, I got an idea: split up the data into smaller paths and apply smooth.spline() to each list element. 然后,我有了一个主意:将数据分成较小的路径,然后将smooth.spline()应用于每个列表元素。 The end goal being to re-integrate the list into a continuous, smooth track. 最终目标是将列表重新整合到连续,流畅的轨道中。

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)

With the resulting error: 结果错误:

Error in xy.coords(x, y) : 
  'x' is a list, but does not have components 'x' and 'y

I'm probably missing something very simple here... Any thoughts? 我可能在这里错过了一些非常简单的内容...有什么想法吗?

Just smooth x-coord and y-coord separately. 只需分别平滑x-coordy-coord If you have a curve y = y(x) , you can certainly represent it by x = x(t), y = y(t) . 如果曲线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)

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM