/license-plate-recognize

License Plate Segmentation and Recognition with OpenCV and Google Vision API

Primary LanguagePython

Segmentação e Reconhecimento de placas de carro

Pequeno projeto de segmentação e reconhecimento de placas de carro utilizando o OpenCV e a google Vision API. Antes de iniciar o projeto é necessário adicionar suas credencias do Google Vision para a utlização da API, Instruções para obter credenciais: aqui.

os.environ["GOOGLE_APPLICATION_CREDENTIALS"]="[PATH].json"   

Substitua "[PATH]" pelo caminho onde suas credencias estiverem salvas na sua máquina.

Segmentação

O processo de segmentação foi totalmente realizado com o auxílio da biblioteca de visão computacional OpenCV e foi dividido em 5 etapas.
-Inicialmente é feito a leitura da imagem e sua conversão para GrayScale, temos o exemplo a abaixo:

Logo depois, aplicamos o cv2.bilateralFilter(), este filtro é bastante útil para remoção de ruídos com um ótima preservação de bordas. você pode encontrar mais informações sobre este método aqui.

É possível perceber como a imagem tem uma aparência mais "cartunista" após a aplicação do filtro.

Agora com a imagem já suavizada é aplicada uma transformação morfológica conhecida como Black-Hat, ela é basicamente a diferença entre a imagem de fechamento (Imagem após as operações de dilatação e erosão) e a imagem de entrada, no nosso caso, a imagem suavizada. Essa operação é muito útil para encontrar "coisas" escuras em fundos brancos, como é o caso dos digitos da placa. Neste link tem mais infomações sobre a operação. Após sua aplicação chegamos no resultado abaixo.

Em seguida aplicamos uma operação de fechamento afim de ressaltar os digitos da placa, pois após a operação black-hat eles obtiveram algumas falhas em seu interior e reduzir alguns ruídos externos. Neste link é possível entender um pouco mais sobre o funcionamento das operações morfológicas. Também iremos realizar uma binarização na imagem. Após o operação e a binarização temos o seguinte resultado.

Como a queremos detectar uma placa, precisamos de alguma forma destacar a placa entre os outros objetos da imagem, para isso iremos utilizar o método cv2.Sobel() ele promove uma operação de alisamento gaussiano conjunto mais diferenciação, no nosso caso iremos usar a derivada na direção X afim de ressaltar os traços verticais (Isso mesmo, verticais! haha), pois são maioria na placa e em seus dígitos. No link é possível entender melhor seu funcionamento. Abaixo temos a imagem após o procedimento.

No entanto a imagem acima perdeu sua formatação dos valores, seus valores não estão mais entre [0-255] e seu "type" não é mais uint8, como de padrão nas imagens por esse fator a imagem acima aparece com tanto ruído. Dessa forma, é necessario realizar uma normalização para resgatar este intevalo de valores e seu type padrão. Após isso temos uma resultado melhor na imagem, como pode ser visto

Com a imagem já normalizada aplicamos um filtro gaussiano com kernel (9x9), afim de reduzir os ruídos restantes, seguida de outra operação de fechamento com o mesmo intuito da aplicada anteriormente. Assim chegamos no resultado abaixo:

Por fim, é realizada outra operação de binarização na imagem. Com a imagem já binarizada aplicamos uma operação de erosão com 3 iterações seguida de uma operação de dilatação de com 9 iterações (Valores obtidos empíricamente). Com a erosão tentaremos reduzir os restantes dos ruídos, porém iremos perder parte da informação da placa, com a dilatação tentaremos recuperar parte dessa informação perdida.

Após os procedimentos iremos enviar a imagem para a função crop que desenvolvi. Ela recebe a imagem após os últimos procedimento(imagem A) e a imagem em escala de cinza(Imagem B). A imagem "A" é submetida ao método cv2.findContourns(), com ela iremos conseguir todos os contornos da imagem e com o auxílio da cv2.boudingRect() conseguimos obter os vértices dos retangulos encontrados. A proporção das placas mercosul são de 40x13, assim temos uma proporção de 3.07. Dessa forma, considerei que apenas os retângulos encontrados que respeitassem uma proporção de valores entre [2-5]. Assim, com os vértices obtidos pude realizar um recorte na imagem em escala de cinza e obter a placa. Atualmente esse algoritimo de segmentação obteve uma acurácia de apenas 70%, porém acredito ser possível aumentar esse valor com a utilização de mais técnicas de processamento de imagem. vértices para

Reconhecimento

O Reconhecimento da placa é realizado através da API Google Vision utilizando técnicas de Reconhecimento Óptico de Caracteres (OCR). Neste link tem a explicação de como utilizar.

Contatos

Instagram
ricksonencaut@gmail.com
LinkedIN