Обнаружение и устранение выбросов в траектории GPS


9

Мне нужно найти алгоритм или метод, который может обнаружить latitude longitude точки выброса на траектории во время постобработки , которая затем может быть исправлена ​​(возвращена на путь траектории на основе ее соседей).

В качестве примера точек выброса, которые я хотел бы обнаружить и исправить, я приложил изображение, демонстрирующее:

Необработанные данные синим цветом.

Я попытался использовать фильтр Калмана без запаха, чтобы сгладить данные как можно лучше, но это, кажется, не работает достаточно эффективно для более экстремальных выбросов (необработанные данные синим цветом, сглаженные данные красным):

Необработанные данные синим цветом, UKF сглаживают данные красным.

Мой UKF не может быть откалиброван должным образом (но я уверен, что это так).

Траектории - это пешеходы, бегуны, велосипедисты - движением человека, которое может начинаться и останавливаться, но не резко меняться в скорости или положении, которые быстро или внезапно.

Решение, которое не опирается на данные о времени (и только на данные о местоположении), было бы чрезвычайно полезным (поскольку обрабатываемые данные не всегда могут содержать данные о времени). Тем не менее, я знаю, насколько маловероятно, что такое решение существует, поэтому я так же счастлив иметь любое решение!

В идеале решение должно обнаружить выброс, чтобы его можно было исправить, что привело бы к исправленной траектории:

Исправлены необработанные данные зеленым цветом.


Ресурсы, которые я просеял:

Ответы:


1

В качестве инструмента для обработки речных сетей я создал инструмент контроля качества для поиска «пиков» в сети. Хотя я не предлагаю вам использовать мой инструмент (как и для обработки речных сетей), я указываю вам на файл справки, который показывает изображение того, что я сделал.

Я разработал код, используя закон косинусов для определения последовательных углов между каждым отрезком прямой ломаной. Вы можете разработать собственный код для этой идеи, чтобы шагать вдоль ломаной линии и определять крайние углы.


Я использовал метод, описанный вами (с использованием закона косинусов) и включающий расстояния между точками, чтобы лучше определить выбросы, и, похоже, он работает очень хорошо. Спасибо!
JP

8

Алгоритм я использую.

  1. Рассчитаем евклидово минимальное остовное дерево точек:

введите описание изображения здесь

  1. Найти 2 точки, наиболее удаленные друг от друга в этой сети

введите описание изображения здесь

  1. Найдите кратчайший маршрут между ними:

введите описание изображения здесь

Как видно, это может привести к резкому повороту.

У меня есть реализация ArcGIS python вышеупомянутого алгоритма, он использует модуль networkx. Дайте мне знать, если это представляет интерес, и я обновлю свой ответ сценарием

ОБНОВИТЬ:

# Connects points to make polyline. Makes 1 line at a time
# Tool assumes that 1st layer in Table of Conternt is TARGET polyline feature class,
# second layer in TOC is SOURCE point fc.
# If no selection found in SOURCE layer, works on entire dataset

import arcpy, traceback, os, sys
import itertools as itt
from math import sqrt
sys.path.append(r'C:\Users\felix_pertziger\AppData\Roaming\Python\Python27\site-packages')
import networkx as nx
from networkx import dijkstra_path_length

try:
    def showPyMessage():
        arcpy.AddMessage(str(time.ctime()) + " - " + message)
    def CheckLayerLine(infc):
        d=arcpy.Describe(infc)
        theType=d.shapeType
        if theType!="Polyline":
            arcpy.AddWarning("\nTool designed to work with polylines as TARGET!")
            raise NameError, "Wrong input\n"
        return d
    def CheckLayerPoint(infc):
        d=arcpy.Describe(infc)
        theType=d.shapeType
        if theType!="Point":
            arcpy.AddWarning("\nTool designed to work with points as SOURCE!")
            raise NameError, "Wrong input\n"
        return d
    mxd = arcpy.mapping.MapDocument("CURRENT")
    layers = arcpy.mapping.ListLayers(mxd)
    if len(layers)<=1:
        arcpy.AddWarning("\nNot enough layers in the view!")
        raise NameError, "Wrong input\n"
    destLR, sourceLR=layers[0],layers[1]
    a = CheckLayerPoint(sourceLR);d = CheckLayerLine(destLR)

#  copy all points to manageable list
    g=arcpy.Geometry()
    geometryList=arcpy.CopyFeatures_management(sourceLR,g)
    nPoints=len(geometryList)
    arcpy.AddMessage('Computing minimum spanning tree')
    list2connect=[p.firstPoint for p in geometryList]
#  create network    
    p=list(itt.combinations(range(nPoints), 2))
    arcpy.SetProgressor("step", "", 0, len(p),1)
    G=nx.Graph()
    for f,t in p:
        p1=list2connect[f]
        p2=list2connect[t]
        dX=p2.X-p1.X;dY=p2.Y-p1.Y
        lenV=sqrt(dX*dX+dY*dY)
        G.add_edge(f,t,weight=lenV)
        arcpy.SetProgressorPosition()
    arcpy.AddMessage(len(G.edges()))
    mst=nx.minimum_spanning_tree(G)
    del G

#  find remotest pair
    arcpy.AddMessage(len(mst.edges()))
    length0=nx.all_pairs_dijkstra_path_length(mst)
    lMax=0
    for f,t in p:
        lCur=length0[f][t]
        if lCur>lMax:
            lMax=lCur
            best=(f,t)
    gL=nx.dijkstra_path(mst,best[0],best[1])
    del mst
    nPoints=len(gL)
    ordArray=arcpy.Array()
    for i in gL: ordArray.add(list2connect[i])

#  append line to TARGET
    curT = arcpy.da.InsertCursor(destLR,"SHAPE@")
    curT.insertRow((arcpy.Polyline(ordArray),))
    arcpy.RefreshActiveView()
    del curT

except:
    message = "\n*** PYTHON ERRORS *** "; showPyMessage()
    message = "Python Traceback Info: " + traceback.format_tb(sys.exc_info()[2])[0]; showPyMessage()
    message = "Python Error Info: " +  str(sys.exc_type)+ ": " + str(sys.exc_value) + "\n"; showPyMessage()            

Хммм интересный подход .. спасибо, что поделились этим! Я уверен, рабочий пример был бы оценен!
Никв

1
Некоторое кусочное сравнение между результатом этого подхода и тем, что вы получите, просто следуя входным данным, может позволить вам установить порог, который избавит от «пиков», но при этом сохранит углы. Это может быть особенно полезно, если у вас также есть информация о времени, связанная с каждой точкой, которая естественно возникает из некоторых журналов.
Даг МакКлин

1
Справедливо. Сценарий легко изменить, не создавая связи между узлами, которые находятся на расстоянии n интервалов времени друг от друга. Я использую скрипт для других вещей, а не для путей GPS. Есть и другие способы улучшения, например, триангуляция, которая значительно сократит количество ссылок в графе
FelixIP

2
Этот метод работает в некоторых случаях, однако форма некоторых траекторий означает, что использование этого метода неосуществимо в моем случае использования. (Проблемы возникают, когда, например, траектория удваивается сама по себе, так как многие узлы игнорируются и она зигзагообразна. Аналогично, целые участки траектории можно игнорировать, если вход / выход этого участка достаточно близко друг к другу).
JP

1
@JP для путей, идущих в обратном направлении, может помочь уплотнить необработанную строку 1
FelixIP

4

Одна идея состоит в том, чтобы создать скрипт, который перечисляет углы (и, возможно, также длину) каждого сегмента вашего пути. Теперь вы можете сравнить значения каждого сегмента с его прямыми соседями (и, возможно, вторыми соседями также для повышения точности) и выбрать все те точки, где значения превышают заданное значение предельного значения. Наконец, просто удалите точки с вашего пути.


Я использовал похожий метод, описанный @Hornbydd, который выполняет это, используя закон косинусов для определения углов, а также учитывает расстояние между точками. Спасибо за предложение.
JP

2

Также стоит обратить внимание на метод Медиана-5.

Каждая координата x (или y) устанавливается равной медиане из 5 значений x (или y) вокруг нее в последовательности (т. Е. Само по себе, два предыдущих значения и два последующих значения).

например, x3 = медиана (x1, x2, x3, x4, x5) y3 = медиана (y1, y2, y3, y4, y5) и т. д.

Метод быстрый и простой в использовании для потоковой передачи данных.



0

Вы можете импортировать ваши данные в Excel или использовать pandas и пометить и / или удалить все расстояния от предыдущей точки, которые превышают некоторый нереалистичный порог расстояния.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.