Reconhecimento de placas veiculares brasileiras

Em função da crescente demanda de novos veículos no Brasil e no mundo, realizar o reconhecimento de placas veiculares se tornou uma aplicação essencial a ser desenvolvida para a engenharia de tráfego. Seu principal objetivo é o de proporcionar o controle de acesso de carros em ambientes controlados, como estacionamentos, e verificar a localização de carros em situações irregulares ou furtados.

Neste artigo, vamos abordar uma solução para realizar o reconhecimento de placas veiculares brasileiras, levando em consideração tanto o modelo antigo como o modelo novo, através do uso de redes neurais convolucionais. Além disso, vamos descrever o funcionamento do sistema desde a detecção da placa na imagem até seu processamento e extração de características.

Adicionalmente, também foi gravado um vídeo dando uma introdução sobre o projeto e o que será apresentado ao longo deste artigo. Sinta-se livre para visualizá-lo e entender melhor o sistema antes de ler o artigo: http://bit.do/lpr_project

Pipeline

Após realizar um estudo profundo sobre as metodologias de reconhecimento de placas veiculares encontradas na literatura, decidiu-se utilizar uma arquitetura de redes neurais sequenciais, conforme ilustra a figura abaixo:

Figura 1: Arquitetura do sistema desenvolvido.

A primeira rede neural recebe uma imagem a partir de uma câmera e tem como objetivo detectar as placas dos carros. Em sua saída, além da imagem apenas da placa do carro, também é informado qual é o tipo da placa, onde existem 3 classes possíveis: o modelo Mercosul, representado pela classe “nova”, e o modelo de placas antigas, representados pelas classes “velha” e “vermelha” (como no modelo antigo existem placas da cor cinza e vermelha, existe essa necessidade de fazer a distinção entre elas). Para realizar essa primeira rede neural, utilizamos a arquitetura do yolo tiny v2.

A segunda rede neural a ser utilizada vai depender de qual tipo de placa foi detectada na etapa anterior. Se for o modelo Mercosul, será a rede neural 2; se for o modelo Antigo, será a rede neural 3. Outra informação de entrada nesta rede é a imagem da placa detectada. O objetivo dessa rede neural é realizar a segmentação dos caracteres presentes na placa. A saída dessa etapa envolve a localização de todos os caracteres encontrados na rede. Assim, como existem sete caracteres em ambos os modelos das placas, essa rede deve informar as coordenadas de sete caracteres. Para esta rede neural, utilizamos a mesma arquitetura desenvolvida por Rayson Laroca, realizando um treinamento especializado para cada tipo de placa.

A terceira rede neural tem como objetivo identificar quais são os caracteres segmentados. Resumidamente, nesta etapa, inicialmente serão utilizadas as informações de localização de cada caractere segmentado para extrair a imagem de cada caractere individual. Em seguida, essas imagens são convertidas para escala de cinza e inseridas na rede neural de identificação de caracteres, que vai informar qual é o caractere mais provável de estar presente na figura analisada.

Neste artigo, vamos concentrar em especificar a arquitetura e os resultados da rede neural de reconhecimento de caracteres (redes neurais 4 e 5 da Figura 1).

Rede neural: Reconhecimento de caracteres

Inicialmente, a rede neural de identificação foi treinada para reconhecer 36 caracteres (26 letras e 10 números). Porém, em certos casos, alguns caracteres que eram números estavam sendo confundidos com letras e vice-e-versa, como por exemplo “B” com “8”, “O” com “0”, “S” com “5”, “I” com “1”, entre outros.

Entretanto, é interessante notar que os dois modelos de placas seguem um determinado padrão na sequência de letras e números, onde nas placas antigas temos LLL-NNNN e nas placas novas temos LLL-NLNN, sendo “L” uma letra e “N” um número. Assim, podemos utilizar essa ideia para aplicar redes neurais especializadas somente em números e somente em letras em função da posição dos caracteres na imagem da placa. Portanto, antes de aplicar a rede neural de reconhecimento, precisamos ordenar todos os caracteres encontrados na imagem (fornecidos pela rede neural de segmentação) em relação as suas coordenadas no eixo horizontal, onde será possível utilizar a rede neural especializada correta em cada um dos caracteres.

Para realizar o reconhecimento de caracteres, realizamos o treinamento de duas redes neurais para cada um dos dois modelos, totalizando quatro redes neurais a serem treinadas. Ou seja, no nosso sistema, teremos uma rede neural de reconhecimento de letras e uma outra rede neural para o reconhecimento de dígitos para os dois modelos de placas.

Em relação a arquitetura dessas redes neurais, tentamos deixar a mais simples possível mas, ao mesmo tempo, que possua um alto valor de acurácia, visto que desejamos um baixo tempo de processamento no nosso sistema final. A arquitetura final da rede de reconhecimento de letras está sendo mostrada na figura abaixo:

Figura 2: Arquitetura da rede neural de reconhecimento de letras.

A rede neural de reconhecimento de dígitos possui a mesma estrutura. Porém, a última camada possui 10 classes ao invés de 26 classes. Além disso, também realizamos diferentes configurações do tamanho da imagem de entrada da rede, onde a que teve um melhor desempenho foi o tamanho 20x20.

Base de dados

O treinamento da rede neural de reconhecimento de caracteres (tanto de números quanto de letras), estava sendo feito utilizando uma base de dados disponibilizado pela UFPR. Entretanto, a maioria das imagens dos caracteres estavam com uma baixa qualidade e resolução se comparado com as imagens que pretendíamos trabalhar.

Para resolver este problema, resolvemos construir uma nova base de dados de caracteres utilizando imagens de placas que tivessem uma melhor qualidade. Dessa forma, com o objetivo de cumprir essa tarefa, analisou-se cada frame de um vídeo de 2 horas de veículos circulando na UFRN.

Através da utilização das redes neurais de detecção de placas de carro e a de segmentação de caracteres, extraímos todas as imagens das placas, seus modelos e a localização de cada caractere correspondente na imagem. Em seguida, com posse dessas informações, foi feita a rotulação manual de todas as placas detectadas. Essa rotulação consistiu em analisar a imagem de cada placa extraída e preencher o conteúdo da placa correspondente manualmente dentro de um arquivo CSV. No total, foram rotuladas 11.328 imagens de placas de carro do modelo antigo e 2.457 do modelo novo, correspondendo a uma base de dados com aproximadamente 38 mil caracteres do modelo antigo e com aproximadamente 11 mil caracteres do modelo novo.

A distribuição das letras e dos números para ambos os modelos dessa nova base de dados está sendo mostrada nas Figuras 3 e 4, respectivamente.

Figura 3: Distribuição de letras nos modelos antigo e novo.
Figura 4: Distribuição de números nos modelos antigo e novo.

É interessante observar que a distribuição é altamente desbalanceada, principalmente no caso das letras. Isso ocorre porque, em geral, a primeira letra de cada placa depende do estado onde o veículo foi regularizado. Como todas as imagens foram tiradas do estado do Rio Grande do Norte, temos que grande parte das letras detectadas são N, O, Q e G, considerando o modelo antigo.

Para que o treinamento da rede neural não se especializasse em apenas algumas letras, resolvemos selecionar uma quantidade específica de amostras para realizar o treinamento com base na classe que tivesse a menor quantidade de amostras, técnica conhecida como undersampling. Testamos diversas configurações para realizar esse treinamento, e as quantidades de amostras que obtiveram o melhor desempenho foram:

  • Letras (modelo antigo): 9880 amostras (380 de cada letra).
  • Letras (modelo novo): 2080 amostras (80 de cada letra).
  • Números (modelo antigo): 9920 amostras (992 de cada número).
  • Números (modelo novo): 5250 amostras (525 de cada número).

O conjunto dessas amostras formam a base de dados de validação e de treinamento.

Pré-processamento das imagens

Depois de criar essa nova base de dados, começamos a refazer o treinamento da rede neural de reconhecimento de caracteres e testar essa nova rede treinada. Porém, percebemos que nos casos onde a placa estava com pouca iluminação, o sistema acabava classificando os caracteres de maneira errada (quase todos estavam sendo identificados como letra “I” ou número “1”). A Figura 5 mostra alguns casos onde os caracteres foram erroneamente identificados.

Figura 5: Exemplos de caracteres com baixa iluminação.

Para entender o motivo desse problema, é necessário inicialmente explicar um princípio básico de redes neurais: antes de todos os caracteres serem processados na rede neural, é preciso realizar um redimensionamento do tamanho da imagem, de forma que todas as imagens possuam o mesmo tamanho. No nosso sistema, como dito anteriormente, escolhemos redimensionar o tamanho desses caracteres para imagens 20x20.

A letra “I” e o número “1” são os caracteres das placas antigas com a menor largura (são representadas apenas por um traço vertical). Assim, quando realizamos esse redimensionamento, temos o seguinte resultado para esses dois casos:

Figura 6: Exemplos de caracteres “1” e “I” depois de realizado o redimensionamento

Dessa forma, como esses dois caracteres possuem uma largura muito pequena, a maior parte da figura resultante fica escura depois de realizar o redimensionamento. Portanto, quando tentamos identificar os caracteres mostrados na Figura 5, a rede neural de identificação de caracteres acaba retornando que o caractere representa o número “1” ou a letra “I”, visto que a maioria dessas imagens também é predominantemente escura.

Para resolver esse problema, aplicamos uma operação de pré-processamento nas imagens antes de carregá-las nas redes neurais. Inicialmente aplicamos uma técnica de binarização adaptativa, utilizando a média das pixels vizinhos para determinar o limiar de binarização, e, em seguida aplicamos as operações morfológicas de erosão e dilatação. Dessa forma, ao invés de representar a imagem dos caracteres em escala de cinza (variando de 0 até 255), representamos essas imagens com apenas com dois valores (0 ou 1). A figura abaixo ilustra o resultado depois de aplicar esse procedimento para os caracteres mostrados na Figura 5:

Figura 7: Exemplo de caracteres depois de aplicar o pré-processamento.

Assim, fizemos o treinamento da rede neural considerando esse pré-processamento e testamos com algumas placas que antes estavam sendo incorretamente identificadas, onde foi possível corrigir esse erro e deixar o sistema menos suscetível a problemas de iluminação. A Figura 8 ilustra um desses casos, onde, inicialmente, todos os números tinham sido incorretamente reconhecidos e, posteriormente, com o retreinamento da rede neural com o pré-processamento, todos os números foram corretamente reconhecidos.

Figura 8: Exemplo da melhora do desempenho do sistema referente a pouca iluminação.

Treinamento da rede neural de reconhecimento de caracteres

Depois de criar a nova base de dados e implementar o pré-processamento descrito acima, realizamos o processo de treinamento das redes neurais de reconhecimento de caracteres.

Utilizamos a base de dados descrita na seção anterior para realizar o treinamento e a validação dos resultados, onde selecionamos aleatoriamente 20% dessa base para fazer a validação e os 80% restante para treinamento.

Além disso, também criamos uma base de dados de teste independente dessas imagens, com o objetivo de avaliar o desempenho da rede neural de forma mais genérica possível. Essa base de dados de validação possui imagens carro, totalizando 746 placas, onde 589 são do modelo antigo e 127 são do modelo novo.

A imagem de entrada de cada caractere possui um tamanho 20x20. Além disso, utilizamos os seguintes hiperparâmetros: Otimizador Adam, com taxa de aprendizagem de 0.001, batch size = 32, epochs=20, para todas as redes neurais.

Resultados

Como descrito anteriormente, fizemos diversos treinamentos das redes neurais em busca daquelas que retornassem o melhor valor de acurácia. Em geral, concentramos em testar diferentes configurações da imagem de entrada e diferentes quantidades de amostras de treinamento. Os resultados mostrados nessa seção representam as melhores configurações encontradas.

Em relação a detecção das placas antigas, foi possível detectar corretamente todos os caracteres em 543 das 589 das placas, o que corresponde a uma acurácia de 92,19%. Além disso, 37 placas tiveram apenas 1 caractere errado, 8 placas tiveram 2 caracteres errados, e apenas 1 placa teve 3 caracteres errados. A matriz de confusão para as letras e os números estão mostrados nas figuras 9 e 10, respectivamente.

Figura 9: Matriz de confusão para as letras do modelo antigo.
Figura 10: Matriz de confusão para os números do modelo antigo.

Analisando as matrizes de confusão, é possível calcular que a acurácia da rede neural de reconhecimento de letras foi de 97.58% e a acurácia da rede neural de reconhecimento de números foi de 99.40%. Resultados que podem ser considerados bastante satisfatórios.

Em relação a detecção das placas novas, foi possível detectar corretamente todos os caracteres em 143 das 157 das placas, o que corresponde a uma acurácia de 91,08%. Além disso, 13 placas tiveram apenas 1 caractere errado, e apenas 1 placa teve 2 caracteres errados. A matriz de confusão para as letras e os números estão mostrados nas figuras 11 e 12, respectivamente.

Figura 11: Matriz de confusão para as letras do modelo novo.
Figura 12: Matriz de confusão para os números do modelo novo.

Analisando as matrizes de confusão das Figuras 11 e 12, é possível calcular que a acurácia da rede neural de reconhecimento de letras foi de 97.92% e a acurácia da rede neural de reconhecimento de números foi de 100%, não apresentando nenhum erro! Resultados que também podem ser considerados bastante satisfatórios.

Finalmente, a Figura abaixo mostra alguns exemplos de resultados finais do sistema desenvolvido.

Figura 13: Exemplos de reconhecimento de placas veiculares brasileiras.

API

Atualmente, estamos desenvolvendo uma API para que qualquer pessoa consiga testar o funcionamento do sistema desenvolvido. A ideia é que o usuário carregue a imagem de um carro (que tenha uma placa) e a API retorne a placa do carro. A figura abaixo mostra a versão atual da página inicial da API:

Figura 14: API do sistema em desenvolvimento.

Assim que finalizarmos a API, vamos disponibilizar a link da mesma para que você consiga testar qualquer imagem de carro que você quiser!

Conclusões

Neste artigo, apresentamos um sistema com redes neurais sequenciais convolucionais que realiza o reconhecimento de placas veiculares brasileiras, considerando os modelos antigo e novo.

Inicialmente, apresentamos a estrutura do sistema, que vai possui no total sete redes neurais: uma para detectar a placa da imagem, duas para fazer a segmentação dos caracteres, e quatro para reconhecer letras e números. Em seguida, descrevemos a construção de uma nova base de dados, que resultou em aproximadamente 38 mil amostras de caracteres dos modelos antigos, e 11 mil caracteres do modelo novo.

Também introduzimos técnicas de processamento de imagem para melhorar o desempenho do sistema considerando casos onde as imagens possuem uma baixa iluminação. Por fim, apresentamos os resultados de acurácia do sistema desenvolvido, onde atingimos um valor de 92,19% para as placas antigas e de 91,08% para as placas novas, que podem ser considerados como resultados bastante satisfatórios.

Referências

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store