
O 2GIS se orgulha da precisão dos dados. Todos os dias de trabalho em cada cidade, nossos especialistas percorrem áreas inteiras para corrigir todas as alterações no mapa - novas casas, estradas e até caminhos. E eles também coletam e colocam sinais de trânsito, ajudando a construir corretamente estradas e vias pedonais. Neste artigo, mostrarei como decidimos ajudar os cartógrafos e começamos a coletar sinais de trânsito automaticamente.
O que é Fiji e por que existem sinais
Fiji é um editor de mapas que desenvolvemos para nossos especialistas em GIS. Este é um aplicativo cliente-servidor clássico. Já existem vários artigos no hub: nos quais falamos sobre Fiji:
Como coletar sinais antes
Fiji tem um modo especial de operação para coletar e atualizar sinais. Nesse modo, o mapeador pode abrir o vídeo gravado pelo DVR. O vídeo em si é exibido em uma janela separada e sua trilha é exibida no mapa. O marcador mostra a posição atual.

Uma grade é aplicada na parte superior do vídeo - ela permite determinar a distância do sinal. Assim que o personagem se torna do tamanho de uma célula, o cartógrafo faz uma pausa e cria o personagem. Neste momento, sabemos a posição atual e a distância do sinal, então avançamos e o atraímos para o link. O link em nossa terminologia é uma representação esquemática de uma seção de estrada. Cada caractere tem seu próprio código numérico, seu cartógrafo entra em um campo especial.
Se já inserimos um caractere, então o carregamos no editor de caracteres. O cartógrafo verifica o vídeo e, se necessário, faz alterações usando os mesmos códigos numéricos. Ou, se o sinal estiver correto, marque-o como atualizado.
Obviamente, esse método exige que o cartógrafo veja cada vídeo - e também gaste tempo inserindo cada caractere. Além disso, a posição do sinal no mapa não é determinada com precisão: simplesmente desviamos da posição atual por uma distância determinada pela grade e, em seguida, traçamos o ponto resultante para a estrada mais próxima. Como resultado, os sinais podem não ser criados exatamente lá (ou nem sequer) quando necessário. Isso significa que o cartógrafo também deve movê-lo para o lugar certo, o que também consome seu tempo. Além disso, o vídeo pode não ter nenhum sinal, mas o cartógrafo ainda é obrigado a vê-lo. Obviamente, o programa permite aumentar a velocidade do vídeo, mas o tempo gasto em qualquer caso será mais que zero. Portanto, decidimos automatizar esse processo.
Como coletar agora
Ainda precisamos de vídeos de registradores. Mas agora, em vez de olhar para cada um, o cartógrafo simplesmente seleciona os arquivos necessários e pressiona o botão "Download". Depois disso, ele pode fazer outras coisas - o vídeo será processado e os sinais de trânsito aparecerão no mapa. Vários casos duvidosos serão notados especificamente. Portanto, tudo o que resta para o cartógrafo é revisar esses casos e corrigi-los.
Arquitetura

Para obter objetos das classes necessárias com os atributos necessários do vídeo, escrevemos vários serviços.
O primeiro é VideoPreprocessingService - é aqui que o arquivo de vídeo é carregado. O serviço envia o arquivo para o repositório, registra-o no banco de dados e cria tarefas para seu processamento. Você precisa cortar os quadros do vídeo com uma certa frequência, selecionar pontos de GPS para eles na faixa para eles e enviar o resultado ao serviço de processamento de quadros.
As duas primeiras tarefas são executadas não pelo serviço em si, mas pelo Worker. Isso é feito para que você possa alterar facilmente o número desses trabalhadores. Assim, aumentando a produtividade, se houver tal necessidade.
FrameProcessingService salva todos os quadros e pontos recebidos. Ele também envia quadros para a fila. É lido por um serviço escrito por nossos colegas especialistas em Machine Learning. Ele reconhece sinais de trânsito. Obviamente, FrameProcessingService lê as respostas desse serviço - esses são os códigos de caracteres, se estiverem no quadro, e os retângulos nos quais esse caractere está inscrito. Sabendo o tamanho do retângulo, entendemos a distância do sinal. E quando todos os quadros do vídeo são processados - ele os envia para o nosso servidor de mapas.
O servidor de mapas é a parte mais importante do sistema. Os clientes recebem dele todos os dados que armazenamos (
exceto os ladrilhos ). Ele salva esses dados e executa toda a lógica de negócios.
Descrição geral
Nossos dados de mapa são objetos geográficos. Um objeto geográfico é uma geometria (ou seja, a localização de um objeto no espaço) e um conjunto de atributos. Nós os armazenamos no banco de dados e operamos neles. Mas, a partir de FrameProcessingService, obtemos apenas o código do sinal, as coordenadas do ponto em que o sinal foi reconhecido, o próprio quadro e a máscara de sinal nesse quadro. Portanto, precisamos transformar esse conjunto de dados em um objeto geográfico. Cada objeto geográfico pertence a alguma classe. Cada tipo de sinal de trânsito é uma classe separada. Podemos facilmente obtê-lo a partir do código do sinal. A partir do código do sinal, podemos obter atributos específicos para esta classe. Por exemplo, recebemos o código 3_24_60. 3_24 - diz que este é um limite de velocidade (assine 3.24 nas regras de trânsito). O valor da restrição deve ser indicado para esses caracteres. Ele nos diz a terceira parte do código - aqui serão 60 km / h.
Portanto, a classe de objetos geográficos é definida, seus atributos também são específicos. Parece que você já pode criar um objeto geográfico. Mas é muito cedo. Primeiramente, cada signo tem um atributo "Direção", que diz em qual direção o signo age. Em segundo lugar, ainda não temos geometria para esse objeto geográfico. Temos um ponto a partir do qual vimos um sinal. Portanto, o próprio sinal está a alguma distância de nós. Além disso, sua geometria afeta o valor do atributo Direção.

Aqui vamos fazer uma pequena digressão. Obviamente, temos uma rede rodoviária. Consiste em links individuais. Cada link é uma linha. Na primeira parte da figura, acabamos de traçar dois links. As setas mostram a direção em que foram desenhadas, ou seja, a esquerda foi desenhada de baixo para cima e a direita - de cima para baixo.
Cada link contém informações sobre em qual direção você pode se mover ao longo dele. A direção do movimento é um atributo separado; não é igual à direção da renderização. Este atributo nos diz em qual direção você pode se mover ao longo do link, em relação à direção do desenho. Na segunda parte da figura, os dois links têm o mesmo valor para esse atributo e na terceira figura - valores opostos.
Como isso se relaciona com os sinais? Então, movemos os links de baixo para cima e vemos algum tipo de sinal. Portanto, no link à esquerda, o sinal terá a direção "Somente reta", à direita - "Somente atrás", ou seja, mesmo que os links da terceira figura. Tudo ficou simples aqui, mas isso ocorre porque nossos links são unidirecionais. Na realidade, um número muito grande de links é bilateral, ou seja, a direção deles tem o significado de "Nas duas direções". E o sinal é sempre direcionado em uma direção, e precisamos entender em que direção.
Correspondência de mapa
Antes de começar a colocar sinais no mapa, precisamos entender quais estradas percorremos quando gravamos o vídeo. Os dados do GPS não são suficientes para isso: geralmente são confundidos com dezenas de metros. Além disso, os mapas ainda são esquemas e também podem não coincidir com o terreno real. Por exemplo, em estradas largas com várias faixas.
Isso resolverá vários problemas de uma vez:
- As placas já podem ser criadas nessas estradas, para que possamos fazer alterações, se houver;
- Alguns desses sinais podem não aparecer no vídeo, e podemos encontrá-los - e colocá-los em um rótulo especial;
- Podemos entender em que caminho estávamos quando vimos algum sinal reconhecido, o que, por sua vez, nos ajudará a colocá-lo no lugar certo no mapa.
Algoritmo
O algoritmo que usamos é bastante simples. Já existe um
artigo sobre Habré com sua descrição. Em termos gerais, soa assim: temos uma estrada selecionada, pegue o ponto GPS mais próximo do final da pista. E com relação a esse ponto, avaliamos as estradas que se juntam ao nosso caminho - ou seja, avaliamos a probabilidade de nosso ponto se referir a essa estrada específica. Cada estrada recebe pontos, aquele com mais pontos é selecionado. Repita até a faixa terminar.
No processo, fizemos várias adições ao algoritmo. O algoritmo não levou em consideração a direção nos links da estrada, então a primeira coisa que fizemos foi começar a considerá-los: agora, se o link for unidirecional, entendemos qual direção devemos seguir ao longo dele. E se essa direção não coincidir com a direção do link, descartamos esse link.
Inicialmente, pareceu-nos que isso seria suficiente, e os primeiros testes confirmaram isso. Mas então começamos a conferir os vídeos gravados em bairros residenciais, e tudo acabou não sendo tão agradável. O fato é que temos uma precisão de dados muito alta, inclusive nas estradas. Assim, desenhamos todas as entradas de automóveis intra-trimestre, até os mínimos detalhes. Por outro lado - como eu disse, o GPS pode não ser muito preciso ou mesmo muito impreciso. E se você for por uma estrada em torno da qual existem prédios altos, os pontos na pista podem sair bastante fortemente. Acontecia que os pontos se moviam em direção a mais de 20 metros. Como resultado, verifica-se que muitos pontos estão próximos das estradas nas quais não seguimos. O resultado do encolhimento dessas faixas foi a seguinte:

O senso comum nos disse que existem poucas placas nessas estradas e, portanto, não há nenhuma razão específica para coletá-las ali. Portanto, provavelmente, na maioria dos casos, o carro se moveu pelas ruas principais. Portanto, para calçadas intra-trimestre, introduzimos uma multa. Com uma multa, entendemos uma diminuição no número de pontos ao longo da estrada. Como resultado, o problema com as entradas de automóveis intra-trimestre foi resolvido - eles não saíam quando não os acompanhamos e, quando realmente os viajávamos, apesar da multa, eles eram a melhor opção e, então, os escolhemos.
Depois disso, os resultados já foram muito bons. E pareceu-nos que o mapeamento estava terminado. Mas o problema veio, de onde eles não esperaram. De repente, verificou-se que há casos em que outra estrada se afasta da estrada e o faz de maneira muito tranquila. E tudo foi agravado pelo fato de que a estrada secundária também pode ser paralela à nossa, pelo menos por algum tempo. Ao mesmo tempo, lembre-se, a trilha do GPS quase nunca está localizada no topo dos links para os quais viajamos, é ligeiramente deslocada para algum lado dela. E, claro, graças a tudo isso, o algoritmo começou a se apegar a esses ramos. Por isso, na melhor das hipóteses, recebemos vários links pelos quais não passamos. E na pior das hipóteses - eles sentaram a pista completamente errada.

Portanto, chegamos a uma avaliação adicional da estrada. Tomamos os pontos anteriores e seguintes da trilha do GPS em relação ao ponto em que selecionamos o link. E vemos que o azimute nesses pontos não difere muito do azimute do movimento ao longo desse link. Se a diferença for muito grande, multaremos este link.
Como resultado, obtivemos um resultado que nos convém, embora algumas vezes ainda ocorram pequenos erros (às vezes é possível escolher um link extra que não passamos). Mas eles são bastante raros e, portanto, não são críticos para nós.
Posicionamento de caracteres
Agora, temos um conjunto de ligações rodoviárias por onde dirigimos e um conjunto de molduras com sinais. Além de informações sobre qual caractere está nesse quadro, a partir de qual ponto da trilha esse quadro e a máscara do caractere são obtidos (um retângulo que descreve o caractere nesse quadro). Então você pode colocar esses sinais no mapa.
A primeira etapa é obter informações adicionais que nos ajudarão a colocar a placa no lugar certo:
- Sinal de azimute. Se a marca estiver localizada exatamente no centro do quadro, ela coincidirá com o azimute no ponto GPS. Se o sinal não estiver centralizado, este é o azimute no ponto + o ângulo entre o centro do quadro e o sinal. Já temos o azimute do ponto GPS e podemos calcular o ângulo entre o centro do quadro e o sinal, porque sabemos onde a máscara de sinalização está localizada no quadro e o ângulo de visualização com o qual o vídeo foi gravado.
- A distância até a marca do ponto GPS. Podemos calcular, porque sabemos o tamanho da máscara de sinalização, a resolução do quadro e o ângulo de visualização com o qual o vídeo é gravado.
Agora você pode ir diretamente para a instalação do sinal. Porque Os pontos na pista nem sempre (mas na verdade nunca) se encontram nos elos da estrada; primeiro, precisamos colocar nosso ponto de detecção de sinal no elo. Fazemos o seguinte:
- Entre as estradas em que a pista estava assentada, deixamos apenas aquelas que atravessam algum tipo de buffer em torno do nosso ponto de GPS;
- Calculamos a distância de cada estrada selecionada e as ordenamos pelo seu aumento;
- Pegamos a estrada, calculamos a projeção do ponto GPS nela;
- Temos a direção com a qual nos movemos neste ponto ao longo desta estrada;
- Se a direção do item 4 for inaceitável nessa estrada, retornaremos ao item 3 e seguiremos a próxima estrada;
- Se a direção for aceitável, pare.
Agora temos o caminho que seguimos quando definimos o ponto GPS e a projeção desse ponto em nossa estrada. De fato, esse caminho e, portanto, o ponto, podem não ser escolhidos corretamente. Por exemplo, nas curvas, é muito fácil cometer um erro.

Portanto, antes de prosseguir, você precisa ter certeza de que não estamos enganados. Ou, se cometer um erro, substitua a estrada pela correta e faça uma projeção nela. Para fazer isso, pegue as estradas que se conectam à nossa estrada e avalie-as por distância e azimute. Como resultado, obtemos a estrada mais adequada para um determinado ponto e construímos uma projeção nela.
Agora que o nosso ponto GPS está parado na estrada, podemos calcular a localização do sinal em relação a ele. Para fazer isso, construa um vetor a partir deste ponto com um comprimento igual à distância do sinal na direção que coincide com o sinal azimute. Depois disso, tentamos puxar a placa para uma das estradas em que nossa pista estava assentada. Nesse caso, levamos em consideração a direção das estradas e a direção do sinal, que é calculado para cada estrada através do azimute do sinal.
Nesta fase, pode acontecer que não existisse estrada adequada. Por exemplo, devido ao fato de o sinal ter uma direção inaceitável nessas estradas (ou seja, são de mão única). Nesse caso, esse sinal está localizado em alguma estrada vizinha na qual não passamos, o que significa que simplesmente não o criaremos.
Agora temos a coordenada do sinal traçado para a estrada, resta verificar se ele está definido adequadamente, porque às vezes podemos cometer um erro. Para fazer isso, verificamos que o sinal não está muito longe do ponto GPS original, comparando essa distância com a distância do sinal obtido através do quadro, com alguma suposição. Verifique também se a marca não está atrás do ponto GPS. Se as validações forem bem-sucedidas, obtemos as coordenadas do sinal na estrada e sua direção, o que significa que nosso objeto geográfico tem geometria e todos os atributos necessários. Você pode continuar para salvá-lo.
Sinais de mesclagem
Na verdade, é muito cedo para passar para a conservação. O fato é que cada sinal pode ser visto de vários quadros, com exceção de alguns casos especiais, quando em algumas partes do quadro o sinal está oculto atrás de qualquer obstáculo, por exemplo, atrás de um caminhão.
Em cada um desses quadros, obtemos um objeto geográfico para o sinal, eles têm os mesmos atributos e estão localizados aproximadamente no mesmo ponto. Isso significa que precisamos deixar apenas um deles. Além disso, se esse sinal não for novo, já o teremos no banco de dados, o que significa que precisamos marcá-lo como atualizado e não criar um novo objeto geográfico.
Para isso, realizamos a mesclagem de novos objetos geográficos entre nós e os existentes.
Primeiro de tudo, temos todos os sinais que já criamos, nos links em que dirigimos. A eles, adicionamos todos os caracteres que reconhecemos dos quadros.
O que precisamos fazer com eles: precisamos entender, a partir de suas classes, atributos e geometrias, que algum conjunto desses objetos geográficos é o mesmo sinal. Se houver um objeto geográfico existente neste conjunto, deixe-o apenas e observe que ele foi atualizado. Se o conjunto contiver apenas novos objetos geográficos, deixe apenas um deles.
Fazemos isso em quatro etapas:
- Agrupe objetos geográficos por sua classe;
- Em cada grupo da etapa 1, obtemos grupos por atributos;
- Para cada grupo da etapa 2, coletamos os grupos por geometria;
- Se houver um sinal existente no grupo da etapa 3, deixamos apenas (se houver vários deles, depois deixamos todos) e, se não houver sinais existentes no grupo, deixamos o que está no meio.
Depois disso, temos o número desejado de caracteres que podem finalmente ser salvos.

Obviamente, pode ser que tenhamos algum tipo de sinal, mas não o reconhecemos no vídeo. Nesse caso, esse símbolo não será atualizado. Infelizmente, não podemos ter certeza de que esse sinal também não esteja mais no chão, porque só poderia ser coberto por algum tipo de obstáculo durante a gravação de um vídeo. Portanto, não excluímos este sinal imediatamente, mas o marcamos como ausente no vídeo. Se esse sinal estiver visível em outro vídeo, simplesmente removemos essa marca e a atualizamos. Se ele ainda não estiver visível - o cartógrafo terá que lidar com esse sinal. E exclua-o se realmente não existir mais.
Planos imediatos
Sinais das estradas laterais
As placas no vídeo não vêm apenas das estradas que dirigimos, mas também das estradas secundárias: podem ser estradas que cruzam a nossa ou adjacentes. Ou vice-versa - estradas que se ramificam nas nossas. Pode até ser estradas paralelas às nossas. É muito difícil distinguir os sinais que existem nessas estradas dos sinais que precisamos. Afinal, muitas vezes eles estão perto da nossa estrada.
Para resolver o problema, planejamos usar várias regras semânticas ao colocar um sinal em um link. Por exemplo, é improvável que um limite de velocidade de 5 km / h esteja na estrada, mas é muito provável que esteja na entrada do posto de gasolina.
Sinais de rastreamento
Às vezes, não mantemos sinais e, às vezes, vice-versa - mantemos sinais que não precisam ser mesclados. Portanto, planejamos rastrear caracteres por quadros - para reconhecer o mesmo caractere em quadros diferentes, mesmo antes de transformá-los em objetos geográficos. E use esse conhecimento com mesclagem.
Conclusão
A versão atual é essencialmente beta. Portanto, é imperfeito. Existem problemas que vamos resolver no futuro próximo. Existem problemas que ainda não estão claros como resolver. , . , GPS- . , — , . , , .
. , . , , - .