Reconhecimento automático de placas de identificação de veículos em uma Jetson Nano usando YOLOv4-tiny e LPRNet

Este post faz parte da série Reconhecimento automático de placas. Leia também os outros posts da série:

Nesta série de artigos vamos apresentar um workflow completo para reconhecimento automático de placas de identificação de veículos usando uma Jetson Nano com uma câmera Raspberry Pi v2 8MP. Durante o desenvolvimento desse workflow, tomamos decisões visando um cenário para reconhecimento de placas de identificação de veículos em portaria para controle de entrada e saída de veículos. Entretanto, este pode ser estendidos para outras aplicações, como monitoramento de trânsito, alterando poucas ou nenhuma das decisões apresentadas. Este primeiro artigo da série aborda sobre a etapa de detecção da placa, responsável por extrair a placa de cada frame para que sejam reconhecidos os caracteres. 

Modelo para detecção de placas

A YOLOv4 é considerada estado da arte para detecção de objetos em imagens, contando com várias versões mais compactas para dispositivos com restrições computacionais. A YOLOv4-tiny é um exemplo de arquitetura mais compacta baseada na YOLOv4, apresentando FPS até oito vezes maior que a YOLOv4 [Techzizou-Medium, 2021]. Ambos modelos possuem pesos pré-treinados com o dataset MS COCO, o qual conta com 80 classes com mais de 330 mil imagens.  

Yolo-v4 vs Yolo-v4 tiny 

Testamos ambos modelos na Jetson Nano usando o framework Darknet com pesos pré-treinados no dataset COCO para avaliar e comparar o desempenho destas. Usamos este vídeo de aproximadamente 1min30s capturado por uma câmera para monitoramento de trânsito localizada na rodovia PST da Tailândia em um momento de trânsito intenso. Usamos o vídeo na resolução 1080p e 720p. No caso da YOLOv4, tanto em 720p e 1080p obteve-se FPS médio de 0,8. Também observamos um perfil similar entre as duas resoluções de uso de memória RAM e SWAP, picos de 3,1GB a 3,3GB de RAM e menos de 100MB de SWAP. Já no caso da YOLOv4tiny, usando o vídeo 720p o FPS médio foi de 12,8 enquanto que com o vídeo de 1080p obteve-se um FPS médio de 5,9. Também foi observado um perfil similar de uso de RAM e SWAP para ambas resoluções, mas menor do que no caso da YOLOv4, com picos de uso de RAM em torno de 2GB e sem uso de SWAP. 

Na Figura 1 mostramos as detecções de um frame selecionado do vídeo resultante do teste com a YOLOv4 em 1080p. Já na Figura 2 mostramos as detecções do mesmo frame obtidas com a YOLOv4-tiny em 1080p. Comparando ambos, notamos que a YOLOv4-tiny falha em detectar objetos menores e mais distantes da câmera, enquanto a YOLOv4 é mais robusta nesses casos. Esse comportamento é esperado já que no conjunto de teste do dataset MS COCO a acurácia da YOLOv4-tiny é cerca de 2/3 da acurácia da YOLOv4.  

Figura 1: Frame do vídeo resultante da YOLOv4 em 1080p com as detecções obtidas. 

Figura 2: Frame do vídeo resultante da YOLOv4-tiny em 1080p com as detecções obtidas. 

No cenário de uso do nosso problema, reconhecimento de placas de identificação de veículos em uma portaria, a câmera geralmente é localizada próxima a cancela da portaria onde os veículos serão parados e então as placas estarão próximas da câmera. Além disso, os caracteres da placa precisam estar legíveis e com boa visibilidade para serem reconhecidos na próxima etapa. Dessa forma, a falta de robustez do modelo YOLOv4-tiny com objetos distantes da câmera não deve afetar o cenário de uso. Neste caso, obter um maior FPS é mais relevante para a aplicação do problema, uma vez que os automóveis não deverão ficar muito tempo parados na cancela. Devido a todas essas implicações, escolhemos o modelo YOLOv4-tiny para ser treinado para detectar as placas de identificação de veículos. 

Dataset Open Images V6 

Para treinamento do modelo de detecção das placas usamos o dataset da Google chamado Open Images, o qual está disponível publicamente. Ele possui cerca de 9 milhões de imagens, e 16 milhões de bounding boxes para 600 classes de objetos, dentre as quais há a “Vehicle registration plate”. Na Figura 3 apresentamos a imagem deste dataset. 

artigo anterior da série

Também selecionamos algumas imagens de outras classes, como por exemplo  “Bicycle”, “Airplane” e “Building”, para incluir no conjunto de treinamento e validação. Essas imagens foram usadas como exemplos negativos, i.e., não possui anotações para a classe alvo “Vehicle registration plate”. Esses exemplos são usados para balancear os exemplos da classe alvo e aumentar a robustez das detecções. Após adicionar esses exemplos, totalizaram 8091 imagens para treinamento e 675 imagens para validação. O conjunto de teste foi composto somente por imagens da classe alvo para avaliar o desempenho do modelo para detecção de placas de identificação de veículos, totalizando em 1113 imagens. 

O OIDv4 ToolKit pode ser usado para fazer o download dos conjuntos de treinamento, validação e teste. Essa ferramenta faz o download de classes específicas e salva as anotações de cada imagem em um arquivo “.txt” correspondente na pasta Label dentro de cada conjunto. Para construir o conjunto de treinamento da classe “Vehicle registration plate” executa-se o código main.py com a opção downloader, o parâmetro –classes indicando a classe desejada e –type_csv indicando o conjunto: treinamento, validação ou teste. 

Para os conjuntos de validação e teste repete-se o mesmo procedimento alterando o parâmetro  –type_csv  para validation e test ,  respectivamente.  Também executamos esses passos para as demais classes que foram usadas como exemplos negativos. Para cada conjunto é criada uma pasta no diretório OIDv4_ToolKit/OID/Dataset e dentro de cada uma dessas pastas, há uma pasta para cada classe de objetos baixada. 

Após realizar o download das imagens, usando o código convert_annotations.py, essas anotações são transformadas para o padrão de anotação de bouding box requerido pelas arquiteturas YOLOv4. Esse código irá realizar esse processo para todos os conjuntos em OIDv4_ToolKit/OID/Dataset, e para cada classe salva na pasta de cada conjunto. Sendo necessário então, executar esse código somente uma vez diretamente no root do diretório OIDv4_ToolKit

Por fim, pode-se remover a pasta Label criada dentro da pasta de cada classe de objetos. Por exemplo, para a classe “Vehicle registration plate”, utilizar os comandos: 

Após esses passos, cada pasta correspondente a uma classe de objetos para cada conjunto de treinamento apresentará para cada imagem um arquivo “.txt” com o mesmo nome, como mostra a Figura 4

Figura 4: Arquivos da pasta Vehicle registration plate do conjunto de treinamento. 

Treinamento do modelo YOLOv4-tiny 

Para o treinamento do modelo de detecção YOLOv4-tiny, utilizamos o framework Darknet. Este possui várias redes neurais implementadas em C e CUDA, incluindo a YOLOv4 e a YOLOv4-tiny. Primeiro passo é clonar este repositório git: 

$ git clone https://github.com/AlexeyAB/darknet 

É importante se atentar aos requisitos descritos no README: 

  • CMake >= 3.18 
  • CUDA >= 10.2 
  • OpenCV >= 2.4 
  • cuDNN >= 8.0.2  
  • GPU with CC >= 3.0 

Utilizamos CMake 3.22.1, CUDA 11.4, cuDNN 8.2.2 e OpenCV 4.1.1. 

Com os todos requisitos corretos, basta compilar o Darknet a partir do Makefile: 

Neste caso, alteramos o Makefile para usar GPU e OpenCV, mas é possível utilizar o framework sem GPU apesar de uma drástica redução no desempenho do treinamento sendo executado somente em CPU.  

Após compilar Darknet com sucesso, são necessárias algumas configurações para realizar o treinamento com o dataset de placas de identificação de veículos. Neste caso em que há um número reduzido de exemplos no conjunto de treinamento e validação, é recomendado fazer o treinamento a partir dos pesos pré-treinados no dataset COCO para que o modelo tenha uma convergência no treinamento mais rápida. Para isso, os pesos pré-treinados estão disponíveis por este link, o qual deve ser salvo no diretório darknet/

O próximo passo é copiar o conjunto de treinamento e validação para o diretório darknet/data. Todos arquivos do diretório OIDv4_ToolKit/OID/Dataset/train que estão em subpastas, representando as diferentes classes de objetos, devem ser copiados para o diretório darknet/data/obj. A Figura 5 apresenta como este diretório deve ficar ao final. Da mesma forma, todos arquivos do diretório OIDv4_ToolKit/OID/Dataset/validation que estão em subpastas, representando as diferentes classes de objetos, devem ser copiados para o diretório darknet/data/test. A Figura 6 mostra como esse diretório deve ficar. Lembrando que essa pasta apesar do nome, contém os exemplos de validação. 

Figura 5: Arquivos copiados das subpastas do diretório


Figura 6: Arquivos copiados das subpastas do diretório OIDv4_ToolKit/OID/Dataset/validation para o diretório darknet/data/test, representando o conjunto de treinamento. 

 Após copiar os arquivos de treinamento para o diretório darknet/data/obj e os de validação para darknet/data/test, é necessário gerar os arquivos darknet/data/train.txt e darknet/data/test.txt com os caminhos relativos das imagens de treinamento e validação, respectivamente. Para isso, usamos os scripts generate_train.py e generate_test.py disponibilizados neste repositório github. Estes scripts devem ser copiados para o diretório darknet/. Para gerar os arquivos train.txt e test.txt em darknet/data/, basta executar: 

Após esses passos, deve-se criar os arquivos obj.names e obj.data em darknet/data/. No arquivo obj.names inclui o nome das classes de interesse, neste caso somente a classe alvo: 

Já no arquivo obj.data descreve-se o número de classes, indica-se a localização dos arquivos train.txt e test.txt, do arquivo com o nome das classes e de um diretório backup no qual serão salvos os pesos durante o treinamento: 

O último passo consiste em criar um arquivo com as configurações de treinamento para a YOLOv4-tiny. Faça uma cópia do arquivo darknet/cfg/yolov4-tiny.cfg nomeando-o como darknet/cfg/custom-yolov4-tiny-detector.cfg. Após, é necessário realizar algumas modificações neste arquivo para adaptar ao problema de detecção de placas, o qual só possui uma classe. A primeira alteração é a variável classes, o qual aparece duas vezes no custom-yolov4-tiny-detector.cfg e está atribuído com o número de classes do dataset COCO, classes=80. Ele deve ser alterado em ambas ocorrências para classes=1. Com a alteração do número de classes, é necessário alterar a quantidade de filtros da última camada convolucional. O bloco de variáveis dessa camada está localizado logo antes dos dois blocos [yolo], sendo necessário alterar a variável filters em ambos blocos. Esse valor deve ser configurado como: 

filters=(classes + 5) * 3    

Neste caso: filters=18 

Além disso, precisamos reduzir os valores das variáveis max_batches  e steps, pois há uma quantidade reduzida de exemplos para treinamento e faremos apenas um fine-tuning. Modificamos para: 

max_batches=8000 

steps=6400.0,7200.0 

A variável steps possui dois valores, o primeiro corresponde a 80% do valor de max_batches e o segundo a 90%. Também alteramos a resolução da imagem de entrada para 640×640, objetivando garantir uma boa resolução para as placas a serem detectadas. Além disso, o número de batches e mini batches foram configurados para 64 e 16, respectivamente. Assim as primeiras linhas do arquivo custom-yolov4-tiny-detector.cfg, que definem a arquitetura e as configurações de treinamento, ficaram como: 

Ao finalizar todos esses passos, o treinamento pode ser realizado pela seguinte linha de comando, certificando-se estar no diretório darknet/

Realizamos o treinamento em um servidor com 16 cores do processador Intel Xeon Gold 6130 CPU 2.10GHz e duas GPUS Tesla T4 16Gb, levando cerca de 5h. A Figura 7 mostra o gráfico gerado pelo Darknet do progresso do treinamento com a loss do conjunto de treino e o mAP calculado no conjunto de validação. 

Figura 7: Progresso da loss de treino e do mAP de validação durante o treinamento da YOLOv4-tiny para detecção de placas de identificação de veículos 

O modelo com melhor mAP no conjunto de validação é salvo no diretório configurado no campo backup do arquivo obj.data, no nosso caso é /storage/backup/yolov4-tiny. O nome do arquivo é custom-yolov4-tiny-detector_best.weights. Este arquivo será usado para realizar inferência na Jetson Nano. 

O processo de treinamento gera um log, o qual salvamos no arquivo output_yolov4-tiny.log. Ao final do treinamento, é calculado o mAP em todo o conjunto de validação usando o melhor modelo. O resultado obtido no conjunto de validação foi: 

IoU = 78.82 % 

[email protected] = 83.86 % 

Para avaliar o conjunto de teste do dataset Open Images, que fizemos o download previamente, copiamos a pasta OIDv4_ToolKit/OID/Dataset/test para o diretório darknet/data/, sobrescrevendo a pasta darknet/data/test que continham os arquivos de validação. Então, geramos o arquivo darknet/data/test.txt novamente executando: 

Após esses passos, esse conjunto de teste pode ser avaliado usando o melhor modelo salvo em /storage/backup/yolov4-tiny/:

O resultado obtido com o conjunto de teste foi: 

IoU = 80.39 % 

[email protected] = 81.67 % 

Observamos que os resultados nos conjuntos de validação e de teste foram similares, indicando que o modelo conseguiu generalizar os padrões de detecção aprendidos. Disponibilizamos o modelo treinado e exportado a partir deste link, na pasta darknet_yolov4-tiny

Próximos passos 

Neste artigo apresentamos os passos adotados para treinar um modelo de detecção de placas de identificação de veículos usando a YOLOv4-tiny. Utilizamos como referências principais estes dois repositórios git: YOLOv4-Cloud-Tutorial e yolov4-tiny-custom_training

 Este artigo é o primeiro passo para o reconhecimento automático de placas veiculares. No próximo artigo exploraremos a identificação dos caracteres da placa detectada. 

Referência

[Techzizou-Medium, 2021] Medium, por Techzizou. YOLOv4 vs YOLOv4-tiny: Training YOLO for Object Detection. 2021. URL: https://medium.com/analytics-vidhya/yolov4-vs-yolov4-tiny-97932b6ec8ec 

Autores

  • Geise Santos
  • Matheus Kowalczuk Ferst
  • Elton de Alencar
  • Lucas Coutinho
  • Murilo Pechoto

Outros artigos da série

<< Modelo para identificação dos caracteres da placa

JUNTE-SE HOJE À COMUNIDADE EMBARCADOS

Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.
Home » Software » Reconhecimento automático de placas de identificação de veículos em uma Jetson Nano usando YOLOv4-tiny e LPRNet
Comentários:
Notificações
Notificar
guest
5 Comentários
recentes
antigos mais votados
Inline Feedbacks
View all comments
Leonardo Miguel
Leonardo
30/05/2022 16:10

Conteúdo incrível, parabéns!

Vinícius Pedro
Vinícius
02/05/2022 11:59

Ótimo conteúdo, parabéns!

Normano Ribeiro
Normano Ribeiro
25/04/2022 11:58

Geise! Muito obrigado por compartilhar! Excelente artigo. Aproveitando, gostaria de trocar umas palavrinhas com você. Agradeço desde já. Abraços!

Talvez você goste:
Nenhum resultado encontrado.