4种插值算法

打印 上一主题 下一主题

主题 1640|帖子 1640|积分 4920

如果有一些稀疏的轨迹,如何将这些轨迹平滑插值处理呢?

方法1:线性插值

方法2:三次样条插值

方法3:贝塞尔曲线插值

方法4:拉格朗日插值


线性插值:在两两相邻的点之间差值,两点间全部插值点都在一条直线上。

贝塞尔曲线:贝塞尔曲线不会经过全部的坐标点,会根据坐标点的排列趋势去拟合出一条相对平滑的从第1个点到末了一个点之间的曲线。

三次样条插值:插值函数会经过全部的坐标点,拟合函数平滑。

拉格朗日插值:点太多,会出现不稳定的结果。见下图:


前三种插值算法都有特定的使用场景,按需使用就好了。
  1. import time
  2. import numpy as np
  3. from scipy.interpolate import interp1d
  4. from scipy.special import comb
  5. def linear_interpolation(route, num_points):
  6.     # 1. 线性插值
  7.     # 将经纬度分开
  8.     lons = np.array([point[0] for point in route])
  9.     lats = np.array([point[1] for point in route])
  10.     # 创建插值函数
  11.     distance = np.cumsum(np.sqrt(np.ediff1d(lons, to_begin=0) ** 2 + np.ediff1d(lats, to_begin=0) ** 2))
  12.     distance /= distance[-1]
  13.     # 创建插值函数
  14.     lon_interp = interp1d(distance, lons, kind='linear')
  15.     lat_interp = interp1d(distance, lats, kind='linear')
  16.     # 生成新的距离点
  17.     new_distance = np.linspace(0, 1, num_points)
  18.     # 插值
  19.     new_lons = lon_interp(new_distance)
  20.     new_lats = lat_interp(new_distance)
  21.     return list(zip(new_lons, new_lats))
  22. def cubic_spline_interpolation(route, num_points):
  23.     # 2. 三次样条插值
  24.     lons = np.array([point[0] for point in route])
  25.     lats = np.array([point[1] for point in route])
  26.     distance = np.cumsum(np.sqrt(np.ediff1d(lons, to_begin=0) ** 2 + np.ediff1d(lats, to_begin=0) ** 2))
  27.     distance /= distance[-1]
  28.     lon_interp = interp1d(distance, lons, kind='cubic')
  29.     lat_interp = interp1d(distance, lats, kind='cubic')
  30.     new_distance = np.linspace(0, 1, num_points)
  31.     new_lons = lon_interp(new_distance)
  32.     new_lats = lat_interp(new_distance)
  33.     return list(zip(new_lons, new_lats))
  34. def bernstein_poly(i, n, t):
  35.     return comb(n, i) * (t ** i) * ((1 - t) ** (n - i))
  36. def bezier_curve(route, num_points=100):
  37.     # 3. 贝塞尔曲线插值
  38.     n = len(route) - 1
  39.     t = np.linspace(0, 1, num_points)
  40.     lons = np.array([point[0] for point in route])
  41.     lats = np.array([point[1] for point in route])
  42.     new_lons = np.zeros(num_points)
  43.     new_lats = np.zeros(num_points)
  44.     for i in range(n + 1):
  45.         new_lons += bernstein_poly(i, n, t) * lons[i]
  46.         new_lats += bernstein_poly(i, n, t) * lats[i]
  47.     return list(zip(new_lons, new_lats))
  48. import matplotlib.pyplot as plt
  49. def plot_routes(original, linear, cubic, bezier):
  50.     plt.figure(figsize=(12, 8))
  51.     # 原始轨迹
  52.     orig_lons, orig_lats = zip(*original)
  53.     plt.plot(orig_lons, orig_lats, 'ro-', label='Original', alpha=0.5)
  54.     # 线性插值
  55.     lin_lons, lin_lats = zip(*linear)
  56.     plt.plot(lin_lons, lin_lats, 'b-', label='Linear', alpha=0.7)
  57.     # 三次样条插值
  58.     cub_lons, cub_lats = zip(*cubic)
  59.     plt.plot(cub_lons, cub_lats, 'g-', label='Cubic Spline', alpha=0.7)
  60.     # 贝塞尔曲线
  61.     bez_lons, bez_lats = zip(*bezier)
  62.     plt.plot(bez_lons, bez_lats, 'm-', label='Bezier', alpha=0.7)
  63.     plt.legend()
  64.     plt.xlabel('Longitude')
  65.     plt.ylabel('Latitude')
  66.     plt.title('Trajectory Interpolation Comparison')
  67.     plt.grid(True)
  68.     plt.show()
  69. if __name__ == '__main__':
  70.     # 原始轨迹数据
  71.     route = [
  72.         [122.123456, 31.123456],
  73.         [122.234567, 31.234567],
  74.         [122.345678, 31.345678],
  75.         [122.456789, 31.456789],
  76.         [122.567890, 31.567890],
  77.         [122.678901, 31.578901],
  78.         [122.789012, 31.789012],
  79.         [122.890123, 31.890123],
  80.         [122.901234, 31.901234],
  81.     ]
  82.     start_time = time.time()
  83.     # 线性插值
  84.     linear_route = linear_interpolation(route, 1000)
  85.     print("线性插值结果 (前5个点):", linear_route[:5])
  86.     print("线性插值用时:", time.time() - start_time, "秒")
  87.     start_time = time.time()
  88.     # 三次样条插值
  89.     cubic_route = cubic_spline_interpolation(route, 1000)
  90.     print("三次样条插值结果 (前5个点):", cubic_route[:5])
  91.     print("三次样条插值用时:", time.time() - start_time, "秒")
  92.     start_time = time.time()
  93.     # 贝塞尔曲线插值
  94.     bezier_route = bezier_curve(route, 1000)
  95.     print("贝塞尔曲线插值结果 (前5个点):", bezier_route[:5])
  96.     print("贝塞尔曲线插值用时:", time.time() - start_time, "秒")
  97.     # 绘制比较图
  98.     plot_routes(route, linear_route, cubic_route, bezier_route)
复制代码
  1. # 4、拉格朗日插值算法
  2. import time
  3. from scipy.interpolate import lagrange
  4. import numpy as np
  5. def lagrange_interp(x, y, x_new):
  6.     """
  7.     Lagrange interpolation
  8.     :param x: x coordinates of data points
  9.     :param y: y coordinates of data points
  10.     :param x_new: x coordinates of new interpolated points
  11.     :return: y coordinates of new interpolated points
  12.     """
  13.     f = lagrange(x, y)
  14.     y_new = f(x_new)
  15.     return y_new
  16. if __name__ == '__main__':
  17.     # 原始数据
  18.     route = [
  19.         [122.123456, 31.123456],
  20.         [122.234567, 31.234567],
  21.         [122.345678, 31.345678],
  22.         [122.456789, 31.456789],
  23.         [122.567890, 31.567890],
  24.         [122.678901, 31.678901],
  25.         [122.789012, 31.789012],
  26.         [122.890123, 31.890123],
  27.         [122.901234, 31.901234],
  28.     ]
  29.     x_list = [i[0] for i in route]
  30.     y_list = [i[1] for i in route]
  31.     # 新数据
  32.     x_new = np.arange(122.123456, 122.990123, 0.01)
  33.     y_new = lagrange_interp(x_list, y_list, x_new)
  34.     # 绘图
  35.     import matplotlib.pyplot as plt
  36.     plt.plot(x_list, y_list, 'o', label='original data')
  37.     plt.plot(x_new, y_new, label='interpolated data')
  38.     plt.legend()
  39.     plt.show()
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

前进之路

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表