Mais

Detectando e corrigindo outliers em uma trajetória GPS


Preciso encontrar um algoritmo ou método que possa detectar valores discrepanteslatitudelongitudepontos em uma trajetória durante o pós-processamento, que pode então ser corrigido (trazido de volta ao caminho da trajetória com base em seus vizinhos).

Como exemplo do tipo de pontos discrepantes que gostaria de detectar e corrigir, anexei uma imagem que demonstra:

Eu tentei usar um filtro de Kalman sem cheiro para suavizar os dados da melhor forma possível, mas isso não parece funcionar com eficiência suficiente para outliers mais extremos (dados brutos em azul, dados suavizados em vermelho):

Meu UKF pode não estar calibrado corretamente (mas tenho quase certeza de que está).

As trajetórias são aquelas de caminhantes, corredores, ciclistas - movimentos movidos por humanos que podem começar e parar, mas não mudar drasticamente em velocidade ou posição tão rápida ou repentinamente.

Uma solução que não dependa de dados de tempo (e apenas de dados de posição) seria extremamente útil (já que os dados sendo processados ​​nem sempre podem conter dados de tempo). No entanto, estou ciente de quão improvável é a existência desse tipo de solução, então estou igualmente feliz por ter qualquer solução!

Idealmente, a solução detectaria o outlier para que pudesse ser corrigido, resultando em uma trajetória corrigida:


Recursos que peneirei:

  • Dados GPS suaves- https://stackoverflow.com/questions/1134579/smooth-gps-data

  • Desafios e soluções comuns de rastreamento geoespacial e GPS- http://www.toptal.com/gis/adventures-in-gps-track-analytics-a-geospatial-primer (a solução parece perder a precisão dos dados)

  • Qual algoritmo devo usar para remover outliers em dados de rastreamento?


Como parte de uma ferramenta de processamento de redes fluviais criei uma ferramenta de controle de qualidade para busca de "picos" na rede. Embora eu não esteja sugerindo que você use minha ferramenta (como ela é para processar redes fluviais), indico o arquivo de Ajuda que mostra uma imagem do que eu fiz.

Eu havia desenvolvido um código usando a lei dos cossenos para identificar ângulos sucessivos entre cada segmento de linha de uma polilinha. Você pode desenvolver seu próprio código em torno dessa ideia para percorrer uma polilinha e identificar ângulos extremos.


Algoritmo que eu uso.

  1. Calcule a árvore de abrangência mínima euclidiana de pontos:

  1. Encontre 2 pontos mais distantes um do outro nesta rede

  1. Encontre o caminho mais curto entre eles:

Como se pode ver, ele pode abrir uma curva em uma curva fechada.

Eu tenho a implementação do ArcGIS python do algoritmo acima, ele usa o módulo networkx. Avise-me se for de interesse e atualizarei minha resposta com o script

ATUALIZAR:

# Conecta pontos para fazer polilinha. Faz 1 linha por vez # A ferramenta assume que a 1ª camada na Tabela de Conternt é a classe de recurso de polilinha TARGET, # a segunda camada em TOC é o ponto SOURCE fc. # Se nenhuma seleção for encontrada na camada SOURCE, funciona em conjunto de dados inteiro import arcpy, traceback, os, sys import itertools como 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 ()) + "-" + mensagem) def CheckLayerLine (infc): d = arcpy .Describe (infc) theType = d.shapeType if theType! = "Polyline": arcpy.AddWarning (" nFerramenta projetada para trabalhar com polilinhas como TARGET!") Levanta NameError, "Entrada errada  n" return d def CheckLayerPoint (infc ): d = arcpy.Describe (infc) theType = d.shapeType if theType! = "Point": arcpy.AddWarning (" nFerramenta projetada para trabalhar com pontos como FONTE!") levanta NameError, "Entrada errada  n" return d mxd = arcpy.mapping.MapDocument ("CURRENT") layers = arcpy.mapping.ListLayers (mxd) if len (layers) <= 1: arcpy.AddWarning (" nNão há camadas suficientes na visualização!") aumenta NameError, "Entrada errada  n" destLR, sourceLR = camadas [0], la yers [1] a = CheckLayerPoint (sourceLR); d = CheckLayerLine (destLR) # copia todos os pontos para a lista gerenciável g = arcpy.Geometry () geometryList = arcpy.CopyFeatures_management (sourceLR, g) nPoints = len (geometryList) arcpy.AddMessage ('Computando árvore de abrangência mínima') list2connect = [p.firstPoint for p em geometryList] # criar rede p = list (itt.combinations (range (nPoints), 2)) arcpy.SetProgressor ("step", "", 0 , len (p), 1) G = nx.Graph () para f, t em 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 # encontre o par mais remoto arcpy.AddMessage (len (mst.edges ())) length0 = nx.all_pairs_dijkstra_path_length (mst) lMax = 0 para f, t em 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]) # anexar linha a TARGET curT = arcpy.d a.InsertCursor (destLR, "SHAPE @") curT.insertRow ((arcpy.Polyline (ordArray),)) arcpy.RefreshActiveView () del curT exceto: mensagem = " 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 ()

Uma ideia é criar um script que lista os ângulos (e talvez o comprimento também) de cada segmento do seu caminho. Agora você pode comparar os valores de cada segmento com seus vizinhos diretos (e possivelmente os segundos vizinhos também para aumentar a precisão) e selecionar todos os pontos onde os valores excedem um determinado valor mínimo. Finalmente, simplesmente exclua os pontos do seu caminho.


Também vale a pena examinar o método Median-5.

Cada coordenada x (ou y) é definida para a mediana dos 5 valores x (ou y) em torno dela em sequência (ou seja, ela mesma, os dois valores anteriores e os dois valores subsequentes).

por exemplo. x3 = mediana (x1, x2, x3, x4, x5) y3 = mediana (y1, y2, y3, y4, y5) etc.

O método é rápido e também fácil de usar em streaming de dados.


Existem alguns dados bons nesta pergunta / respostas.

Embora tudo dependa de como seus pontos estão agrupados, o que funcionará / não funcionará. Você precisará ter cuidado com os pontos que estão espalhados, mas não com valores discrepantes.


Você pode importar seus dados para o Excel ou usar pandas e sinalizar e / ou excluir todas as distâncias do ponto anterior que excedem algum limite de distância irreal.


Assista o vídeo: Funkcja wykrywania podwyższonej temperatury ciała - testo FeverDetection (Outubro 2021).