R语言如何按帧筛选与前序坐标最近的对象并过滤冗余行
R语言实现逐帧最近邻轨迹点去重
实现思路
- 按
object字段拆分不同对象的轨迹,各对象轨迹独立处理,避免跨对象误匹配 - 每个对象的最小帧(示例中为frame=1)仅存在1条记录,直接作为首个匹配参考点
- 按帧号从小到大逐帧遍历:对当前帧下所有坐标点,计算其与上一帧保留参考点的欧氏距离,仅保留距离最小的记录,将该记录更新为新的参考点供下一帧匹配
- 仅含1条记录的帧无需计算距离,直接保留即可
完整实现代码
# 加载数据处理依赖 library(dplyr) # 构造示例输入数据 raw_df <- tibble( frame = c(1,2,3,3,4,4,5,5,5,6,1,2,3,3,4,4,5,5,5,6), object = c(rep(6,10), rep(7,10)), x = c(150,149,148,140,148.5,142,147,138,135,146.5,125,126,127,119,117,123,115,124,118,124.5), y = c(100,99,98,90,97,93,96,92,90,99,200,197,202,185,183,199,190,202,192,199) ) # 单对象轨迹逐帧匹配函数 match_closest_traj <- function(traj_subset) { # 按帧号升序排列 traj_subset <- arrange(traj_subset, frame) # 初始化结果集,存入第一帧记录作为初始参考点 result <- list() first_frame <- min(traj_subset$frame) result[[1]] <- traj_subset[traj_subset$frame == first_frame, ][1, ] # 遍历剩余所有帧 rest_frames <- sort(unique(traj_subset$frame))[-1] for (cur_frame in rest_frames) { # 提取当前帧所有候选点 cur_points <- traj_subset[traj_subset$frame == cur_frame, ] # 提取上一帧保留的参考点 last_ref <- result[[length(result)]] # 计算所有候选点到参考点的欧氏距离 cur_points$dist <- sqrt((cur_points$x - last_ref$x)^2 + (cur_points$y - last_ref$y)^2) # 筛选距离最小的点,移除临时距离字段 keep_row <- cur_points[which.min(cur_points$dist), ] |> select(-dist) # 加入结果集 result[[length(result) + 1]] <- keep_row } # 合并所有行返回 bind_rows(result) } # 按对象分组应用匹配函数,得到最终结果 final_df <- raw_df |> group_by(object) |> group_modify(~match_closest_traj(.x)) |> ungroup()
结果验证
运行print(final_df)即可得到和预期完全一致的输出,每帧仅保留1条匹配到的最近点记录:
# A tibble: 12 × 4 object frame x y <dbl> <dbl> <dbl> <dbl> 1 6 1 150 100 2 6 2 149 99 3 6 3 148 98 4 6 4 148.5 97 5 6 5 147 96 6 6 6 146.5 99 7 7 1 125 200 8 7 2 126 197 9 7 3 127 202 10 7 4 123 199 11 7 5 124 202 12 7 6 124.5 199
注意事项
- 逻辑默认不同
object的轨迹完全独立,不会跨对象匹配点,和需求规则对齐 - 若某帧存在多个点与参考点距离完全相等,默认保留数据中排序靠前的记录
- 若需要适配非从1开始的帧编号,代码无需修改,会自动识别每个对象的最小帧作为起始点
内容的提问来源于stack exchange,提问作者iamsaad
相关产品推荐
相关产品推荐

