paint-brush
Como Automatizamos a Verificação de Fotos de Carrospor@indrivetech
6,747 leituras
6,747 leituras

Como Automatizamos a Verificação de Fotos de Carros

por inDrive.Tech9m2023/07/05
Read on Terminal Reader
Read this story w/o Javascript

Muito longo; Para ler

inDrive pede aos usuários para tirar uma foto de seu carro todos os meses. Nossos moderadores verificam manualmente as fotos antes e depois. O problema com a abordagem atual é que é mais difícil aumentar o número de moderadores do que escalar a infraestrutura. Queremos dar ao usuário pistas sobre por que a foto fornecida não “encaixa na conta”

People Mentioned

Mention Thumbnail
featured image - Como Automatizamos a Verificação de Fotos de Carros
inDrive.Tech HackerNoon profile picture

Neste artigo, contarei como automatizamos o processo de verificação do veículo do usuário. Compartilharei com você os componentes que usamos e como organizamos o processo.


No inDrive, usamos muito conteúdo visual. Estamos presentes nas mais diversas regiões marcadas por diferentes mentalidades onde é utilizada uma abundância de documentação diferente: passaportes, certidões e documentos de veículos.


Além disso, há os próprios motoristas e seus veículos para lidar.


Quando se fala em conforto de viagem e melhor qualidade de serviço para nossos usuários, segurança e eliminação de imprevistos são absolutamente essenciais. Por exemplo, quando o carro que estaciona não é o que você reservou.


Você descobrirá como nós da inDrive atualmente lidamos com verificações regulares de veículos. Feito isso, nossos moderadores verificam manualmente as fotos antes e depois. Claro que o processo de verificação envolve outras coisas também, mas aqui vamos nos concentrar apenas neste aspecto.


O problema com a abordagem atual é que é mais difícil aumentar o número de moderadores do que escalar a infraestrutura. Especialmente quando se trata de lidar com dados pessoais dos usuários.

Sobre a tarefa em mãos

Vamos colocar o problema de forma muito simples, como se fosse para uma criança: temos duas fotos de um carro — ambas são do mesmo carro? Obviamente, qualquer um poderia lidar com essa questão, mas as coisas se tornam muito mais complicadas quando adicionamos um critério de comparação.


Por exemplo, certifique-se de que não é uma captura de tela de um telefone celular ou que os números das placas são uma correspondência perfeita.



Globalmente, esse problema pode ser resolvido de várias maneiras: Usando modelos E2E e conjuntos desses modelos.


O modelo E2E envolve um grande modelo (provavelmente uma rede neural) que pode responder às nossas perguntas com base em um par de imagens, como “É o mesmo veículo da foto ou não?”, “Os números da placa correspondem acordado ou não?”, etc.


O problema com esses modelos é que eles exigem muitos dados para aprender e não entendem por que a resposta é o que é.


Por exemplo, se treinarmos um modelo para responder "sim"/"não" com base em um par de fotos, não é mais possível descobrir os motivos da resposta.


Assim, os usuários não conseguirão entender o que queremos deles e teremos que trazer moderadores.


Essa abordagem de ponta a ponta não nos convém. Queremos dar ao usuário pistas de por que a foto fornecida não “cabe com a conta”: "É melhor tirar a foto em um local bem iluminado", "Parece que não vemos o carro inteiro em a foto" ou "O número da placa não corresponde às informações fornecidas".

Qualidade e base do modelo

É muito importante para nós que o modelo não responda "sim" quando há veículos diferentes. Vamos nomear essa métrica como “FPR” (taxa de falsos positivos) e usá-la para mostrar a porcentagem de respostas "sim" versus todos os exemplos negativos (onde os veículos não correspondem).


Agora, vamos apresentar outra métrica — TPR — para medir a proporção de respostas "sim" para todas as respostas afirmativas.


Basicamente, essas duas métricas já são suficientes para descrever nossa tarefa ao otimizar o modelo: Minimizar o FPR e garantir que o TPR não seja muito degradado.


Adotamos a abordagem do conjunto de modelos. Portanto, podemos adicionar todas as nossas ideias ao esqueleto da solução finalizada (esse esqueleto será chamado de “linha de base”). Vamos explorar sua aparência e dividi-la em partes.



Na verdade, ele consiste em vários modelos que processam independentemente duas imagens na entrada e fornecem o número da placa do veículo e seu vetor na saída. Como resultado, com base nos detalhes comparados, é tomada uma decisão de verificação sobre as duas fotos em análise.


Este é o esqueleto do algoritmo que usamos para adicionar vários outros modelos, colocando-os em diferentes nós do nosso modelo. Por exemplo, ao avaliar a qualidade de uma foto, seus níveis de clareza, luz e saturação.


Às vezes, precisamos detectar tentativas de envio de fotos que não são genuínas. Para fazer isso, adicionamos um pré-processador que verifica a foto em busca de ataques de falsificação.


Ao usar essa abordagem, é crucial ter ciclos claros de iteração do produto e gerar um bom conjunto de dados de teste. Adicionamos um novo modelo para avaliar esses dois fatores, “Resolve o problema atribuído?” e “Quanto isso modifica as métricas da solução anterior?”


Vamos agora falar sobre os blocos de construção básicos da solução.

Detecção e segmentação são tudo o que você precisa

Vamos passar a dar uma olhada na terminologia. A seguir, explicarei o significado de termos como "caixa delimitadora" e "máscara de segmentação".


Uma caixa delimitadora é uma forma retangular usada para incluir um objeto de interesse específico. Por exemplo, se quisermos identificar o rosto do gato, definiríamos uma caixa delimitadora contornando-a em vermelho. É definido pelas coordenadas de seus pontos inferior esquerdo e superior direito dentro da imagem.


A segmentação refere-se à tarefa de atribuir um rótulo de classe a cada pixel individual em uma imagem de entrada. No contexto de nossa discussão, isolamos o gato segmentando-o do fundo.



Em nosso modelo, o fundo do veículo não nos interessa porque não fornece informações relevantes para moldar nossa solução de destino. Mas isso não significa que não temos ideias sobre como melhorar nossos modelos usando planos de fundo.


Para enfrentar o desafio de separar os veículos do fundo, pegaremos um modelo da família YOLO (You Only Look Once) e o treinaremos para segmentar imagens de carros. O problema aqui é que temos um grande número de fotos de usuários com mais de um carro na foto.


Para superar esse problema, podemos empregar a seguinte abordagem:


  • Calcule a distância entre o centro de massa da caixa delimitadora e o centro da foto.


  • Determine o tamanho da caixa delimitadora.


  • Classifique as caixas delimitadoras em ordem crescente com base na distância do centro e em ordem decrescente com base no tamanho da caixa.


  • Selecione o primeiro objeto na lista classificada. Consequentemente, obtemos a caixa delimitadora que está mais próxima do centro da imagem, embora seja a maior.


Ótimo, temos nossa primeira entrada.



O próximo passo é encontrar o número da placa do veículo. Em quase todos os países, a placa está localizada na frente. Os raros casos em que as placas de veículos estão localizadas em locais inusitados estão fora do escopo deste artigo.


A abordagem mais comum para estabelecer o número da placa do carro é detectar a caixa delimitadora e aplicar OCR ao patch resultante.


Mas, como nossos experimentos mostraram, o OCR é muito menos eficaz (e leva mais tempo em alguns modelos) se a placa do veículo não estiver paralela ao horizonte.


Isso é especialmente relevante para nossos dados, onde pedimos que os motoristas tirem fotos em ângulo.



A solução que decidimos foi segmentar o número e depois suavizar a linha de contorno obtida. No nosso caso, a tarefa de segmentação foi abordada de forma semelhante à segmentação de veículos, com o seguinte resultado:



Em seguida, desenhamos uma linha de contorno usando a máscara e aplicamos ConvexHull para suavizá-la. Este algoritmo simples suaviza (endireita) as concavidades de nossa linha de contorno, tornando-a mais reta. Isso pode ser descrito como um número menor de ângulos em um polígono de contorno.


Em um mundo ideal, esta operação nos daria um retângulo definido por quatro pontos.



Depois de alinhar as bordas, repetimos o mesmo exercício com a perspectiva, para que o número do registro fique suave, bem apresentado e bem visível. Essa abordagem é especialmente útil quando um carro é muito fotografado em um ângulo em que a placa é pouco visível.


O que é uma correção de perspectiva? Lembro-me da minha aula de álgebra como funciona uma matriz de rotação. Se você pegar um quadrado no sistema de coordenadas cartesianas e multiplicar cada coordenada por uma matriz de rotação de 30 graus, seu quadrado no novo sistema de coordenadas será girado em 30 graus.



Aqui, estamos lidando com uma tarefa semelhante — vamos pegar a linha de contorno e mover todos os pontos para o novo sistema de coordenadas. O problema é encontrar uma matriz de transformação adequada.


Todos esses algoritmos já estão bem estabelecidos, portanto, a única coisa que precisamos fazer é garantir que eles estejam configurados corretamente para a tarefa em questão.



O resultado foi ótimo. Isso aumentou o TPR em quase 15 pontos percentuais. Em seguida, aplicamos algum software de OCR leve e de alta qualidade, como a arquitetura PARSeq.

codificador de carro

A partir de agora, esta é a mais recente tecnologia de rede neural para processar fotos de veículos. Embeddings são uma técnica amplamente adotada em vários campos de aprendizado de máquina, incluindo pesquisa, recomendações e compactação de dados.


No contexto de nossa tarefa, incorporações são empregadas para avaliar a similaridade entre os veículos.


Vejamos um exemplo em que tirei uma foto do meu carro primeiro do lado direito e depois do lado esquerdo. Agora, posso calcular os embeddings (vetores) para essas imagens e, se esses vetores estiverem próximos no espaço, isso indica que é o mesmo veículo.


Mas as incorporações fornecem outra propriedade útil que pode ser usada no produto: se seu modelo de incorporação funcionar bem, você poderá pesquisar o que estiver mais próximo entre as amostras de incorporação. Por exemplo, para encontrar veículos não únicos no sistema.


Ao treinar nosso modelo de incorporação usando dados do inDrive, tomamos precauções meticulosas. Removemos diligentemente todos os dados pessoais das fotos e garantimos que o conjunto de dados fosse normalizado, abrangendo imagens de todos os países em que operamos e níveis de qualidade variados.


Essa abordagem visa evitar a discriminação contra indivíduos que podem não ter acesso a smartphones caros para capturar fotos de alta qualidade.


Consequentemente, obteve um conjunto de dados agrupados por marca e marca de veículo. Depois de fazer vários experimentos, percebemos que teríamos que ficar sem comparar as cores dos veículos por enquanto.


Ao selecionar a arquitetura para nosso modelo, buscamos um backbone que encontrasse um equilíbrio entre desempenho e eficiência computacional. Era crucial evitar o uso de um backbone excessivamente grande, pois isso poderia diminuir significativamente o tempo de execução da linha de base.


Após uma consideração cuidadosa, optamos por eficientenet_b2 como nossa arquitetura de backbone, complementada pela utilização do Additive Angular Margin Loss para fins de aprendizado de máquina.


O objetivo do nosso modelo é aprender representações vetoriais onde os veículos da mesma marca e modelo, como todos os Audi A4s, são posicionados juntos no espaço vetorial.


Em contraste, os Audi A5s seriam posicionados um pouco mais longe dos Audi A4s, mas ainda mais próximos em comparação com, por exemplo, um Toyota Camry.


Agora, vamos nos aprofundar em alguns exemplos de comparações de veículos:



Na parte superior, temos dois carros idênticos, enquanto na parte inferior, temos dois carros diferentes. Vamos revisitar as pontuações de similaridade: o par superior tem uma pontuação de 0,989, enquanto o par inferior tem uma pontuação de 0,697. Ao definir um valor limite de 0,98, podemos classificar os veículos como idênticos.


No entanto, é importante observar que nosso modelo ainda não está funcionando perfeitamente. Temos um viés no fator em questão:




O modelo produz um resultado de 0,751, enquanto idealmente queremos um valor próximo de zero para diferentes veículos.


A principal questão aqui decorre do treinamento de nosso modelo em conjuntos de dados focados principalmente em modelos e marcas de veículos. Consequentemente, o modelo tornou-se proficiente em distinguir entre diferentes veículos, mas tem dificuldades ao avaliar as diferenças dentro das classes de veículos.


O segundo problema que encontramos é que o veículo pode ser mostrado em ângulos diferentes, o que afeta negativamente a qualidade de nossas incorporações devido ao conjunto de dados limitado.


Como primeira etapa, do lado do cliente, adicionamos máscaras e orientamos o motorista sobre como tirar uma foto do carro. O segundo passo será detectar diferentes partes do veículo para posicioná-lo no espaço e estimar sua rotação.



Muitas heurísticas podem ser desenvolvidas aqui para escolher o ângulo correto de rotação. E o mais importante, esses modelos podem ser reutilizados posteriormente para avaliar a condição do veículo. Mas isso é história para outra hora.


Postado por Ilya Kaftanov .