- Pré-requisitos
- Etapas envolvidas no reconhecimento de placas de veículos usando Raspberry Pi
- 1. Detecção de placa de carro
- 2. Segmentação de personagem
- 3. Reconhecimento de personagem
- Casos de falha no reconhecimento da placa do número
- Outros exemplos de sucesso
A segurança sempre foi uma grande preocupação para a humanidade. Hoje temos câmeras de vigilância em escolas, hospitais e todos os outros locais públicos para nos fazer sentir seguros. De acordo com um levantamento do HIS, estima-se que existiam cerca de 245 milhões de câmeras de segurança instaladas e funcionando em 2014, o que é como ter uma câmera de segurança para cada 30 pessoas neste planeta. Com o avanço da tecnologia, especialmente em processamento de imagem e aprendizado de máquina, é possível tornar essas câmeras mais inteligentes treinando-as para processar informações do feed de vídeo.
O feed de vídeo dessas câmeras pode ser usado para realizar o reconhecimento de rosto, análise de padrões, análise de emoção e muito mais, o que realmente o aproximaria de algo como o “Olho de Deus” mostrado no filme FF7. Na verdade, empresas de vigilância como a Hikvision e muitas outras já começaram a implementar esses recursos em seus produtos. Anteriormente, usamos o processamento de imagem MATLAB para ler a matrícula. Hoje, neste artigo, aprenderemos como reconhecer e ler o número da matrícula de automóveis usando Raspberry Pi e OpenCV. Usaremos algumas imagens aleatórias de veículos do Google e escreveremos um programa para reconhecer a placa de número usando OpenCV Contour Detection e, em seguida, leremos o número da placa usando Tesseract OCR. Parece interessante, certo! Então, vamos começar.
Pré-requisitos
Como dito anteriormente, usaremos a Biblioteca OpenCV para detectar e reconhecer rostos. Portanto, certifique-se de instalar a biblioteca OpenCV no Raspberry Pi antes de prosseguir com este tutorial. Além disso, alimente seu Pi com um adaptador 2A e conecte-o a um monitor para facilitar a depuração.
Este tutorial não explicará como exatamente o OpenCV funciona. Se você estiver interessado em aprender o processamento de imagens, verifique os fundamentos do OpenCV e os tutoriais avançados de processamento de imagens. Você também pode aprender sobre contornos, detecção de blob, etc., neste tutorial de segmentação de imagens usando OpenCV. Faremos algo semelhante a isso para detectar a placa do carro a partir da imagem.
Etapas envolvidas no reconhecimento de placas de veículos usando Raspberry Pi
O reconhecimento de placas de veículos, ou LPR, envolve três etapas principais. As etapas são as seguintes
1. Detecção da placa do carro : A primeira etapa é detectar a placa do carro. Usaremos a opção de contorno no OpenCV para detectar objetos retangulares para encontrar a placa do número. A precisão pode ser melhorada se soubermos o tamanho exato, a cor e a localização aproximada da placa do número. Normalmente, o algoritmo de detecção é treinado com base na posição da câmera e tipo de placa de matrícula usada naquele país específico. Fica mais complicado se a imagem nem tiver carro, neste caso daremos um passo adicional para detectar o carro e depois a placa.
2. Segmentação de personagem: Depois de detectar a placa, temos que recortá-la e salvá-la como uma nova imagem. Novamente, isso pode ser feito facilmente usando o OpenCV.
3. Reconhecimento de Caracteres: Agora, a nova imagem que obtivemos na etapa anterior certamente terá alguns caracteres (Números / Alfabetos) escritos nela. Assim, podemos realizar OCR (Optical Character Recognition) nele para detectar o número. Já explicamos o reconhecimento óptico de caracteres (OCR) usando Raspberry Pi.
1. Detecção de placa de carro
A primeira etapa neste leitor de placas de licença Raspberry Pi é detectar a placa de carro. Vamos pegar uma imagem de amostra de um carro e começar detectando a placa desse carro. Em seguida, usaremos a mesma imagem para segmentação e reconhecimento de caracteres também. Se quiser ir direto para o código sem explicação, você pode rolar até a parte inferior desta página, onde o código completo é fornecido. A imagem de teste que estou usando para este tutorial é mostrada abaixo.
Etapa 1: redimensione a imagem para o tamanho necessário e depois a escala de cinza. O código para o mesmo é fornecido abaixo
img = cv2.resize (img, (620.480)) grey = cv2.cvtColor (img, cv2.COLOR_BGR2GRAY) # converter para escala de cinza
O redimensionamento nos ajudamos a evitar problemas com imagens de resolução maior, certifique-se de que a placa da matrícula ainda permaneça no quadro após o redimensionamento. A escala de cinza é comum em todas as etapas de processamento de imagem. Isso acelera outro processo seguinte, desde que não tenhamos mais que lidar com os detalhes de cor ao processar uma imagem. A imagem seria transformada mais ou menos assim quando esta etapa fosse concluída
Passo 2: Cada imagem terá informações úteis e inúteis, neste caso para nós apenas a placa é a informação útil, o resto é praticamente inútil para o nosso programa. Essa informação inútil é chamada de ruído. Normalmente, o uso de um filtro bilateral (Desfoque) removerá os detalhes indesejados de uma imagem. O código para o mesmo é
cinza = cv2.bilateralFilter (cinza, 11, 17, 17)
A sintaxe é destination_image = cv2.bilateralFilter (source_image, diâmetro do pixel, sigmaColor, sigmaSpace). Você pode aumentar a cor sigma e o espaço sigma de 17 para valores mais altos para desfocar mais informações de fundo, mas tome cuidado para que a parte útil não fique desfocada. A imagem de saída é mostrada abaixo, como você pode ver os detalhes do fundo (árvore e construção) estão desfocados nesta imagem. Dessa forma, podemos evitar que o programa se concentre nessas regiões posteriormente.
Etapa 3: A próxima etapa é interessante, onde realizamos a detecção de bordas. Há muitas maneiras de fazer isso, a maneira mais fácil e popular é usar o método astuto da OpenCV. A linha para fazer o mesmo é mostrada abaixo
edged = cv2.Canny (cinza, 30, 200) #Perform Edge detecção
A sintaxe será destination_image = cv2.Canny (source_image, thresholdValue 1, thresholdValue 2). O Threshold Vale 1 e Threshold Value 2 são os valores de limite mínimo e máximo. Apenas as arestas que têm um gradiente de intensidade maior que o valor de limite mínimo e menor que o valor de limite máximo serão exibidas. A imagem resultante é mostrada abaixo
Passo 4: Agora podemos começar a procurar contornos em nossa imagem, já aprendemos como encontrar contornos usando OpenCV em nosso tutorial anterior, então apenas procedemos da mesma forma.
nts = cv2.findContours (edged.copy (), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cnts = imutils.grab_contours (cnts) cnts = classificado (cnts, key = cv2.contourArea, reverse = True) screenCnt = Nenhum
Assim que os contadores forem detectados, nós os classificamos do grande ao pequeno e consideramos apenas os primeiros 10 resultados, ignorando os outros. Na nossa imagem o balcão pode ser qualquer coisa que tenha uma superfície fechada mas de todos os resultados obtidos o número da placa também estará lá, visto que também é uma superfície fechada.
Para filtrar a imagem da placa entre os resultados obtidos, percorreremos todos os resultados e verificaremos qual tem o contorno em forma de retângulo com quatro lados e figura fechada. Uma vez que uma placa de carro seria definitivamente uma figura retangular de quatro lados.
# loop em nossos contornos para c em cnts: # aproximar o contorno peri = cv2.arcLength (c, True) approx = cv2.approxPolyDP (c, 0.018 * peri, True) # se nosso contorno aproximado tiver quatro pontos, então # nós podemos assumir que encontramos nossa tela se len (aprox) == 4: screenCnt = pausa aprox
O valor 0,018 é um valor experimental; você pode brincar com ele para verificar qual funciona melhor para você. Ou vá para o próximo nível usando o aprendizado de máquina para treinar com base em imagens de carros e, em seguida, use o valor certo lá. Assim que encontrarmos o contador certo, salvamos em uma variável chamada screenCnt e desenhamos uma caixa retangular ao redor dele para ter certeza de que detectamos a placa de carro corretamente.
Etapa 5: agora que sabemos onde está a placa do número, as informações restantes são praticamente inúteis para nós. Portanto, podemos prosseguir com o mascaramento de toda a imagem, exceto no local onde está a placa do número. O código para fazer o mesmo é mostrado abaixo
# Mascarando a parte que não seja a placa do número mask = np.zeros (gray.shape, np.uint8) new_image = cv2.drawContours (mask,, 0,255, -1,) new_image = cv2.bitwise_and (img, img, mask = mascarar)
A nova imagem mascarada aparecerá algo como abaixo
2. Segmentação de personagem
A próxima etapa do reconhecimento da placa do número do Raspberry Pi é segmentar a placa do carro da imagem, cortando-a e salvando-a como uma nova imagem. Podemos então usar essa imagem para detectar o personagem nela. O código para cortar a imagem roi (região de interesse) da imagem principal é mostrado abaixo
# Agora crop (x, y) = np.where (mask == 255) (topx, topy) = (np.min (x), np.min (y)) (bottomx, bottomy) = (np.max (x), np.max (y)) Cortado = cinza
A imagem resultante é mostrada abaixo. Normalmente adicionado ao corte da imagem, também podemos cinza e bordar, se necessário. Isso é feito para melhorar o reconhecimento de caracteres na próxima etapa. No entanto, descobri que funciona bem mesmo com a imagem original.
3. Reconhecimento de personagem
A etapa final neste reconhecimento da placa de número do Raspberry Pi é realmente ler as informações da placa de número da imagem segmentada. Usaremos o pacote pytesseract para ler caracteres da imagem, assim como fizemos no tutorial anterior. O código para o mesmo é fornecido abaixo
#Leia a placa do número text = pytesseract.image_to_string (Cropped, config = '- psm 11') print ("Número detectado é:", texto)
Já explicamos como configurar um mecanismo Tesseract, então aqui novamente, se necessário, podemos configurar o OCR Tesseract para obter melhores resultados, se necessário. O personagem detectado é então impresso no console. Quando compilado, o resultado é mostrado como abaixo
Como você pode ver, a imagem original tinha o número “HR 25 BR9044” e nosso programa detectou que ela imprimiu o mesmo valor na tela.
Casos de falha no reconhecimento da placa do número
O arquivo de projeto completo deste Raspberry Pi License Plate Recognition pode ser baixado aqui, ele contém o programa e as imagens de teste que usamos para verificar nosso programa. Sem ser dito, é preciso lembrar que os resultados desse método não serão precisos . A precisão depende da clareza da imagem, orientação, exposição à luz etc. Para obter melhores resultados, você pode tentar implementar algoritmos de aprendizado de máquina junto com isso.
Para ter uma ideia, vejamos outro exemplo em que o carro não está de frente para a câmera.
Como você pode ver, nosso programa foi capaz de detectar a placa do carro corretamente e cortá-la. Mas a biblioteca Tesseract falhou em reconhecer os personagens corretamente. Em vez do “TS 08 UE 3396” real, o OCR reconheceu que era “1508 ye 3396”. Problemas como esse podem ser corrigidos usando imagens de melhor orientação ou configurando o mecanismo Tesseract .
Outro cenário de pior caso é quando o contorno não consegue detectar a placa de carro corretamente. A imagem abaixo tem muitas informações de fundo e iluminação ruim que o programa ainda não conseguiu identificar a placa a partir do número. Nesse caso, temos que recorrer novamente ao aprendizado de máquina ou melhorar a qualidade da imagem.
Outros exemplos de sucesso
Na maioria das vezes em que a qualidade e a orientação da imagem estão corretas, o programa conseguiu identificar a placa e ler o número nela. As fotos instantâneas abaixo mostram alguns dos resultados bem-sucedidos obtidos. Novamente, todas as imagens de teste e o código usado aqui estarão disponíveis no arquivo ZIP fornecido aqui.
Espero que você tenha entendido o reconhecimento automático de matrículas usando Raspberry Pi e tenha gostado de construir algo legal por conta própria. O que mais você acha que pode ser feito com OpenCV e Tesseract ?, Deixe-me saber sua opinião na seção de comentários. Se você tiver alguma dúvida sobre este artigo, fique à vontade para deixá-la na seção de comentários abaixo ou usar os fóruns para outras questões técnicas.