平滑连续2D点 [英] Smoothing Continuous 2D Points

查看:173
本文介绍了平滑连续2D点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Thanks to @user20650 and @李哲源 Zheyuan Li, here is the solution I came up with:

# 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)

我正在尝试平滑动物轨迹的锯齿状路径,以更精确地确定它们的长度.数据采用(x,y)2D坐标的形式.

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.

我拥有的示例数据集相当大(3600行),可以更好地说明问题的范围.它可以在此处作为.Rdata文件使用:

The example data set I have is rather large (3600 rows) to better illustrate the scope of the problem. It is available as an .Rdata file here:

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

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

将smooth.spine()应用于整个数据集是不适当的,因为这些动物蜿蜒很多(循环行走等).

Applying smooth.spine() to the entire data set was inappropriate as these animals meander quite a lot (walking in loops and such).

然后,我有了一个主意:将数据分成较小的路径,然后将smooth.spline()应用于每个列表元素.最终目标是将列表重新整合到连续,流畅的轨道中.

Then, I got an idea: split up the data into smaller paths and apply smooth.spline() to each list element. 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)

出现错误:

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?

推荐答案

分别平滑x-coordy-coord.如果您有曲线y = y(x),则可以肯定地用x = x(t), y = y(t)表示.

Just smooth x-coord and y-coord separately. If you have a curve y = y(x), you can certainly represent it by 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)

这篇关于平滑连续2D点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆