AIS数据修复-三次样条插值法(Cubic spline interpolation)

"前面我们讨论了关于船舶AIS的压缩(这里主要指船舶的轨迹),压缩方法其中包括:基于时间比率的算法、基于时间-速度-航向的算法和基于改进的DP算法。"

在本次博客中,我们对船舶轨迹的修复方法做一个总结。由于船舶在航行的过程中会受到各种异常问题的影响,如 “AIS的位置传感器导致的异常、AIS信号传输过程导致的轨迹异常和AIS网络通信阻塞导致的轨迹异常等” ,进而导致船舶轨迹点不连续。现有的船舶轨迹修复方法有,基于几何的方法,基于人工智能的方法等。本此我们主要研究基于几何的方法——三次样条插值法。

三次样条插值法涉及到《数值分析》,我们对修复原理不再阐述,可参考《舶舶AIS轨迹异常的自动检测与修复算法》一文。下面针对船舶轨迹的部分段缺失,编写了修复算法——三次样条插值法。

1、首先导入所用到的包:

注意 “pycubicspline” 是自定义的.py文件,这个文件参考了Github上一篇大牛的博客。

# -*- coding: utf-8 -*-
"""
    Description :   三次样条插值法
    Author :        张尺
    date :          2022/07/15
"""
import math
import warnings
import pycubicspline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

"""-----设置属性防止中文乱码及拦截异常信息-----"""
plt.rcParams['font.sans-serif'] = [u'SimHei']
plt.rcParams['axes.unicode_minus'] = False
warnings.filterwarnings('ignore', category=FutureWarning)

2、第二部分主要完成的是,把EXCEL中的AIS数据赋值到列表Interpolation_data中。

"""-----主函数-----"""
fig = plt.figure()
AIS_MMIS = []              # 储存各个船舶的MMSI号
AIS_MMIS_NUM = 15          # MISS号的个数,手动输入
AIS_MMIS_NUM_LIST = []     # MISS号每个船舶,对应的经纬度个数
shipdata = pd.read_excel("测试数据(15条).xlsx")

mmsi = shipdata['MMSI']
Lon =  shipdata['Lon']
Lat =  shipdata['Lat']
Temporary_variable_miss = mmsi[0]

# print(shipdata.index)    # 获取行的索引名称
# print(shipdata.columns)  # 获取列的索引名称
AIS_MMIS.append(mmsi[0])   # 先赋值第一个船舶的MMSI号

"""-------创建要插值的数据的AIS_MMIS_NUM个向量-------"""
Interpolation_data = list()
for i in range(AIS_MMIS_NUM):
    Interpolation_data.append([])
"""-------统计各个MMSI号,经纬度个数-------"""
i = 0
j = 1
while i < len(Lon):
    if mmsi[i] == Temporary_variable_miss:
        j = j + 1
        Temporary_variable_miss = mmsi[i]
    else:
        AIS_MMIS_NUM_LIST.append(j)
        AIS_MMIS.append(mmsi[i])
        j = 1
        Temporary_variable_miss = mmsi[i]
    i = i + 1
AIS_MMIS_NUM_LIST.append(j)
AIS_MMIS_NUM_LIST[0] = AIS_MMIS_NUM_LIST[0] - 1
print(AIS_MMIS_NUM_LIST)
print(AIS_MMIS)
"""-------往各个MMSI号的列表中加入对应经纬度组的个数-------"""
i = 0
j = 0
while i < AIS_MMIS_NUM:
    for j in range(AIS_MMIS_NUM_LIST[i]):
        Interpolation_data[i].append([])
    i = i + 1

"""-------往Interpolation_data赋值-------"""
i = 0
j = 0
k = 0
for i in  range(AIS_MMIS_NUM):
    for j in range(AIS_MMIS_NUM_LIST[i]):
        Interpolation_data[i][j].append(Lon[k])
        Interpolation_data[i][j].append(Lat[k])
        k = k + 1
    i = i + 1

3、△ 第三部分,也是最重要的一部分。

(1)插值船舶轨迹的数据,一是经度 lon,二是纬度 lat。我们需要把 lon 或者 lat 任意一个作为插值坐标系中的 x 轴和 y 轴。考虑到最后的可视化效果,我们以 lon 作为 x 轴、以 lat 作为 y 轴。

(2)我们想得到的是,本算法对任意船舶的轨迹都能进行插值。而在实验过程中,我发现如果碰到一些“特殊”的船舶轨迹,程序就跑不动了。经过了很长一段时间的思考和调试,我发现两个相邻的轨迹点 lon 不能相等,这就意味在 x轴上,两个相邻点的横坐标是不能相等的,这也是因为在三次样条插值法时,涉及到了求一个点的导数,如果两个点的横坐标相等,求得的这点导数是无穷的,就会导致程序终止。因此,我们写了一个算法,把即将要插值轨迹中两个相邻轨迹点 lon 变的不重复。算法如下(为了方便大家测试以 lat 作为x轴,也同时编写了相邻轨迹点 lat 不重复的代码):

"""-------去除重复数据-lon-------"""
i = 0
Interpolation_data_new = []
for i in range(AIS_MMIS_NUM):
    Interpolation_data_new.append([])
i = 0
j = 1
while i < AIS_MMIS_NUM:
    Interpolation_temp = Interpolation_data[i][0][0]
    Interpolation_data_new[i].append(Interpolation_data[i][0])
    while j < AIS_MMIS_NUM_LIST[i]:
        if Interpolation_data[i][j][0] != Interpolation_temp:
           Interpolation_data_new[i].append(Interpolation_data[i][j])
        Interpolation_temp = Interpolation_data[i][j][0]
        j = j + 1
    j = 1
    i = i + 1
"""-------去除重复数据-lat-------"""
""" 
i = 0
Interpolation_data_new = []
for i in range(AIS_MMIS_NUM):
    Interpolation_data_new.append([])
i = 0
j = 1
while i < AIS_MMIS_NUM:
    Interpolation_temp = Interpolation_data[i][0][1]
    Interpolation_data_new[i].append(Interpolation_data[i][0])
    while j < AIS_MMIS_NUM_LIST[i]:
        if Interpolation_data[i][j][1] != Interpolation_temp:
           Interpolation_data_new[i].append(Interpolation_data[i][j])
        Interpolation_temp = Interpolation_data[i][j][1]
        j = j + 1
    j = 1
    i = i + 1
"""

4、开始插值,并画图。

"""-------开始插值,一个循环体-------"""
i = 0
while i < AIS_MMIS_NUM:
    Interpolation_data_x = [row[0] for row in Interpolation_data_new[i]] # 原始数据——取第一列数据 lon
    Interpolation_data_y = [row[1] for row in Interpolation_data_new[i]] # 原始数据——取第二列数据 lat
    print("Spline ship: ", AIS_MMIS[i] ,'   '  , i)
    x, y, yaw, k, travel = pycubicspline.calc_2d_spline_interpolation\
        (Interpolation_data_x, Interpolation_data_y,num=int(len(Interpolation_data_x)*1.3))

    """ -------画图------- """
    plt.clf()  # 用于画多个图时, 清空画面
    # -------画图——图1------- #
    ax1 = fig.add_subplot(211)  # 211,指的就是将这块画布分为2×1,然后1对应的就是1号区
    plt.scatter(Interpolation_data_x, Interpolation_data_y, marker='o')
    plt.title(u'原始数据分布')
    # -------画图——图2------- #
    ax2 = fig.add_subplot(212)
    plt.scatter(x, y, marker='o')
    plt.title('Cubic_spline')
    plt.pause(2)  # 显示秒数

5、插值结果如下图1-图3所示。  

图1  修复轨迹图

图2  修复轨迹图

 图3  修复轨迹图

可以看到,利用三次样条插值法对缺失的轨迹段进行修复,得到的船舶完整轨迹是很成功的。

参考文献:吴建华,吴琛,刘文,郭俊纬.舶舶AIS轨迹异常的自动检测与修复算法[J].中国航海,2017,40(01):8-12+101.

完整工程(数据集+Python)和参考论文,在我的博客“资源”界面下,需要下载~

欢迎留言,欢迎指正~
 

  • 7
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
### 回答1: AIS (Adaptive Incremental Smoothing) 轨迹压缩算是一种精度可控的轨迹压缩算,适用于传感器网络、移动设备等限制资源的环境中。算思路是利用数据点之间的距离信息,逐步降低轨迹精度,直到压缩比例满足用户设定的阈值,从而达到最小化轨迹数据量,保证压缩后轨迹与原始轨迹的误差在用户容忍范围内的目的。 在 Python 中实现 AIS 轨迹压缩算的具体步骤如下: 1. 导入必要的库和模块。包括 NumPy、SciPy、Matplotlib 等。 2. 定义一个叫做“compute_distance”的函数,用于计算数据点之间的距离。可以使用欧几里得距离、曼哈顿距离等多种距离定义,根据具体需求而定。 3. 定义一个叫做“smooth_trajectory”的函数,用于根据用户设定的压缩比例和距离信息,实现逐步降低轨迹精度。具体过程是:首先按照一定的间隔计算原始轨迹中相邻点之间的距离;然后根据用户设定的压缩比例,选择相邻数据点之间的最大距离作为窗口大小,对每个窗口内的数据点进行平滑处理,即采用均值或者中位数等方得到一个新的数据点作为压缩后的点。重复进行此操作,直到达到用户设定的压缩比例。 4. 进行数据可视化,比较压缩前后的轨迹。 总之,AIS 轨迹压缩算是一种高效可控的轨迹压缩方,在 Python 等编程语言中都有较为完善的实现。在实际应用中,可以根据具体需求和环境选择最适合的算和实现方式,以达到最佳的压缩效果。 ### 回答2: AIS(Adaptive Image Segmentation)轨迹压缩算是一种可以实现轨迹数据压缩的算,使用Python进行实现。该算首先对轨迹数据进行抽稀处理,将数据进行一定程度的简化。然后,通过聚类算轨迹数据进行分组,使得轨迹之间有一定的相似性。最后,利用不同分组间的相似度进行相应的压缩处理,实现轨迹数据的压缩。 在Python中实现AIS轨迹压缩算可以使用scikit-learn库中的聚类算实现轨迹的分组。此外,还可以使用pandas库进行数据的处理和分析。对于大规模数据的处理,也可以使用多线程技术进行加速处理。 总之,AIS轨迹压缩算是一种非常有效的数据压缩算,可以在保证数据质量的前提下实现数据的压缩,同时使用Python进行实现也十分方便。 ### 回答3: AIS(Adaptive-Interval-Smooth)轨迹压缩算是一种常用的轨迹数据压缩技术。该算可以在存在大量轨迹数据时,将数据量压缩至合理的大小,并保留轨迹信息的完整性。Python是一种广泛使用的编程语言,拥有强大的数据处理和分析功能,因此使用Python来实现AIS轨迹压缩算非常合适。 在Python中,实现AIS轨迹压缩算的步骤如下:首先读取轨迹数据,将数据按时间轴排序,并将轨迹点按照距离相近的方式合并成线段。然后,通过调整参数来自适应地压缩每个线段,并确保良好的压缩效果。最后,将所有压缩后的轨迹数据合并成一个数据集,可以进行可视化显示或进行其他数据分析操作。 使用Python实现AIS轨迹压缩算,可以大大提高数据处理的效率和精度,并且可以进行更加复杂和多样化的数据分析。由于Python语言强大的数据处理和可视化功能,它已成为轨迹数据分析领域的重要工具和编程语言。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值