? Reconocimiento de matrículas vehiculares | OpenCV, Pytesseract (OCR) – Python
Ya se han tratado varios temas en este blog sobre visión por computador empleando OpenCV, por lo que me he sentido impulsada (basándome en el contenido previo de las publicaciones/videos) a crear este post relacionado con la detección de placas de autos y a identificar los caracteres que aparecen en ellas.
Debo decir que lo que quisiera mostrarte hoy es una aplicación que engloba detección de bordes, detección de figuras geométricas, entre otros, que no necesita por ahora de machine learning (que es algo que espero desarrollar en un futuro). Y claro, como no tiene un proceso de aprendizaje puede que esta aplicación únicamente se pueda aplicar bajo cierta iluminación o ángulo y distancia de la cámara al auto, entre otros. Sin embargo, si se te permitiera controlar estas u otras condiciones, puede que tengas muy buenos resultados.
En gran medida en este programa se usará contenido que ya hemos visto, por lo tanto cuando sea necesario lo citaré para que puedas profundizar algún tema (si es que fuera necesario), de igual manera lo haré si se presenta algún tema nuevo en el blog. ¡Así que abre tu editor de código favorito y empecemos a realizar la detección de placas vehiculares junto con sus caracteres!.
CONTENIDO
- ¿Qué es el Reconocimiento Automático de Matrículas (ANPR)?
- ¿Qué es el Reconocimiento Óptico de Caracteres (OCR)?
- ¿Cómo usar OCR en Python?
- Empezando la aplicación
- Leyendo la imagen y transformarla a binaria
- Encontrando contornos
- Determinando el área de los contornos
- Encontrar el rectángulo de la matrícula
- Discriminando contornos y obteniendo el aspect ratio
- Una vez obtenida la placa… ¡Es hora de aplicar OCR con pytesseract!
- Finalmente, ¡visualización!
- Programa completo
- Resultados
¿Qué es el Reconocimiento Automático de Matrículas (ANPR)?

Figura 1: Reconocimiento de matrículas (Fuente).
ANPR pos sus siglas en inglés Automatic number plate recognition, también llamado Licence Plate Recognition (LPR), es un método de vigilancia en masa que permite detectar dentro de una imagen a la placa de un auto y posteriormente utilizando Reconocimiento Óptico de Caracteres (OCR) determinar cada uno de los alfanuméricos que componen a dicha matrícula, de tal modo que esta información pueda ser usada con algún fin.
Si buscas información sobre reconocimiento de matrículas en internet, podrás encontrar varios videos en donde se puede apreciar el registro de entrada y salida a ciertos lugares como estacionamientos, unidades educativas, residenciales o el uso de esta tecnológica en peajes, entre otros. Incluso como a mí me pasó al buscar información para desarrollar este tutorial, te podrías topar con varias empresas como esta, que ofrecen servicios y/o productos que permiten reconocer placas con gran precisión y velocidad, sin importar el país o la cámara que se use.
Por ello si estás desarrollando alguna aplicación sobre este tema, te recomiendo que analices muy bien las características que encuentres en cada uno de los servicios que ofertan distintas empresas, o estudios desarrollados sobre este reconocimiento. De tal modo que tomes dichas características como referencia, y a su vez, que estas puedan guiarte a agregar robustez al programa que estés desarrollando.
¿Qué es el Reconocimiento Óptico de Caracteres (OCR)?

Figura 2: Reconocimiento óptico de caracteres (Fuente).
Optical Character Recognition (OCR), es un proceso automático mediante el cual se extrae texto de una imagen y se transforma a un formato digital, almacenando caracteres, números y símbolos en forma de datos, a los cuales podremos acceder y manipular.
Si pensamos en alguna aplicación, podríamos por ejemplo usar OCR para digitalizar el contenido de un documento, de este modo nos ahorraríamos el pasar manualmente todo ese contenido. Podríamos también extraer los caracteres y dígitos de placas de autos, certificados, registros, entre otros. Cabe destacar que la imagen de entrada puede contener no solo texto impreso sino también escrito a mano.
¿Cómo usar OCR en python?
El motor de reconocimiento óptico de caracteres que emplearemos es tesseract, cuyo desarrollo ha sido financiado por Google desde el 2006, es de código abierto y considerado como uno de los más precisos. Si deseas más información puedes acceder a su manual de usuario, en donde encontrarás su documentación, los idiomas con los que trabaja según la versión que instales o como mejorar la extracción de caracteres, entre otros.
Para acceder a tesseract usando Python necesitamos del paquete pytesseract. Si aún no lo has instalado te recomiendo seguir los pasos de este post de Pyimagesearch. También puedes encontrar información sobre su instalación en su repo en github.
1. Empezando la aplicación
La imagen que escogí para poder realizar la detección de placas y sus caracteres contiene un auto el cual está visto de frente, donde se puede apreciar claramente su placa. Esta no es una imagen tomada de la realidad, sino que es una imagen tratada de un spot publicitario. Sin embargo al final haré pruebas del código con imágenes descargadas de internet que si corresponden a un entorno real.
La imagen con la que vamos a trabajar es la siguiente:

Figura 3: Imagen de entrada.
1.1 Leyendo la imagen y transformarla a binaria
import cv2 import pytesseract placa = [] image = cv2.imread('auto001.jpg') gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) gray = cv2.blur(gray,(3,3)) canny = cv2.Canny(gray,150,200) canny = cv2.dilate(canny,None,iterations=1)
Línea 1: Importamos openCV.
NOTA: Si usas Windows, es posible que necesites añadir pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract'
en la línea 3.
Línea 2: Importamos pytesseract
que será el paquete que nos ayudará a extraer los caracteres de la placa.
Línea 4: Declaramos placa
un array vacío que nos permitirá almacenar la imagen a la matrícula encontrada. Esto lo veremos luego.
Línea 6: Leemos la imagen de entrada que corresponde a la figura 3.
Linea 7 y 8: Transformamos la imagen de BGR a escala de grises, mientras que en la siguiente línea aplicamos cv2.blur
para disminuir el ruido que pueda presentar la imagen, puedes asignar otros valores dependiendo de la imagen sobre la que estés trabajando (¿más información sobre cv2.blur?, aquí te dejo la documentación de OpenCV).
Línea 9 y 10: Aplicamos cv2.Canny
a la imagen a escala de grises para poder encontrar los bordes que presente la imagen. He establecido 150
y 200
como primer y segundo umbral, luego de algunas pruebas (aquí tienes otro tutorial en donde apliqué canny). En la línea 10 aplicamos dilatación (doc de OpenCV) a la imagen, esto permitirá engrosar las líneas blancas que obtuvimos al aplicar la detección de bordes, lo que nos servirá para cerrar el contorno correspondiente a la placa en caso de que haya estado abierto.
Hasta aquí debemos asegurarnos que exista área en blanco que esté rodeando a la placa, con ello ya podremos trabajar en los siguientes pasos.
Si visualizamos la imagen, tendríamos:

Figura 4: Imagen obtenida de la variable canny.
1.2 Encontrarndo contornos
En un principio vamos a aplicar la función cv2.findContours y visualizaremos los contornos, luego procederemos a determinar la matrícula.
#_,cnts,_ = cv2.findContours(canny,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)#OpenCV 3 cnts,_ = cv2.findContours(canny,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)#OpenCV 4 cv2.drawContours(image,cnts,-1,(0,255,0),2)
Línea 12 y 13: Procedemos a encontrar los contornos de canny
que es la imagen binaria que habíamos conseguido antes. Puedes emplear la línea 12 o 13 dependiendo de la versión de OpenCV que tengas instalado. Esta vez he usado cv2.RETR_LIST
para obtener todos los contornos de la imagen, si tienes dudas sobre este argumento y en sí sobre cv2.findContours
puedes visitar este post: ?? CONTORNOS y como DIBUJARLOS en OpenCV y Python.
Línea 14: Para dibujar todos los contornos encontrados vamos a ayudarnos dela función cv2.drawContours
. Si visualizamos obtendremos lo siguiente:

Figura 5: Visualización de los contornos encontrados.
Como podemos apreciar en la figura 5, se han dibujado un motón de contornos, y eso puede preocuparnos porque el único que realmente necesitábamos era el que rodea la placa.
¿Qué podemos hacer?, no te preocupes, en la figura 5 podemos apreciar que sí se ha encerrado el contorno correspondiente a la placa, lo que necesitamos ahora es desechar aquellos contornos no deseados Para ello podemos diferenciarlos basándonos en su área, intentando de encontrar la forma rectangular dela matrícula, entre otros. Veamos.
1.2.1 Determinando el área de los contornos
for c in cnts: area = cv2.contourArea(c)
Línea 16: Como necesitamos analizar cada contorno almacenado en cnts
, nos ayudamos de un for.
Línea 17: Para determinar el área de un contorno usaremos la función cv2.contourArea
. Te recomiendo imprimir en cada momento la variable area
, para que puedas darte cuenta en que rango está la correspondiente a la matrícula.
NOTA: Puedes determinar un área mínima y/o máxima para que el contorno sea considerado como una placa. La cantidad que especifiques para ello corresponderá también a la distancia a la que esté ubicada la matrícula de la cámara, dicho de otro modo, mientas más lejos esté la cámara del auto, más pequeña se va a apreciar la matrícula, mientras que si se acerca, la matrícula se visualizará más grande.
Incluso podrías tomar esos datos y establecer a qué distancia de la cámara-auto puede funcionar tu aplicación. Así eliminaras también aquellos contornos pequeños que no corresponden al área de interés.
1.2.2 Encontrar el rectángulo de la matrícula
¿Recuerdas el post en el que hablamos de como detectar figuras geométricas simples?, Si tu respuesta es no o un «más o menos», te dejo este post: Detectando FIGURAS GEOMÉTRICAS (??⬛) con OpenCV – Python. En este habíamos hablado de como detectar un rectángulo en una imagen y eso es precisamente lo que vamos a realizar en esta aplicación.
x,y,w,h = cv2.boundingRect(c) epsilon = 0.09*cv2.arcLength(c,True) approx = cv2.approxPolyDP(c,epsilon,True)
Línea 19: Obtenemos los puntos x
, y
, w
y h
que rodean a cada contorno, esto nos ayudará para luego determinar el aspect ratio del contorno y determinar que se trate de un rectángulo.
Línea 20 y 21: Obtenemos approx
, que es en donde se almacenará el número de vértices del contorno, para ello usamos la función cv2.approxPolyDP
que a su vez usa epsilon
de la línea 20. Aquí el porcentaje que he usado es de 9%, pero tu podrías cambiarlo para experimentar. Si estás batallando un poco para entender lo que hacen estas líneas te recomiendo este tutorial.
1.2.3 Discriminando contornos y obteniendo el aspect ratio
if len(approx)==4 and area>9000: print('area=',area) #cv2.drawContours(image,[approx],0,(0,255,0),3)
Línea 23: Ahora vamos a usar un condicional. Si el número de vértices es 4 y el contorno tiene un área mayor a 9000 es potencialmente una placa.
Línea 24: Puedes imprimir el área de los contornos que estan siendo potencialmente considerados como una placa, para modificar la condición de la línea 23 y adaptarlo a tu aplicación.
Línea 25: Si descomentas esta línea, podrás dibujar el contorno que está siendo considerado como placa bajo la condición de la línea 23. Obtendrías algo así:

Figura 6: Contorno dibujado luego de aplicar las condiciones de la línea 23.
Hasta ahora todo va de maravilla, pero podríamos añadir más criterios para detectar la placa, como por ejemplo el aspect ratio del contorno para determinar que sea un rectángulo, pero además… también podrías averiguar el alto y ancho de las placas vehiculares de tu país y trabajar también con su aspect ratio.

Figura 7: Medidas de las placas de autos de Ecuador (fuente)
.
En la figura 7 por ejemplo tenemos las medidas de las placas de Ecuador, entonces podríamos determinar su aspect ratio. ¿Recuerdas cómo obtener el aspect ratio de un contorno?.
Entonces el código sería:
aspect_ratio = float(w)/h
Bien, si calculamos el aspect ratio de la placa es decír 404/154 obtendríamos 2.62, entonces podríamos comparar con un valor cercano a este. Para dejar un margen de error, concretamente usaré para este tutorial 2.4.
if aspect_ratio > 2.4:
NOTA: El criterio de aplicar el aspect ratio según las medidas de la placa vehicular es una sugerencia que podrías o no aplicar. Si deseas no aplicar esto, únicamente debes comparar con que el aspect ratio sea mucho mayor a 1, para que el contorno sea considerado un rectángulo.
1.3 Una vez obtenida la placa… ¡Es hora de aplicar OCR con pytesseract!
Ahora que establecimos condiciones para poder encontrar el área en donde se encuentra la placa, deberemos trabajar sobre ese área para obtener sus caracteres y dígitos.
placa = gray[y:y+h,x:x+w] text = pytesseract.image_to_string(placa,config='--psm 11') print('PLACA: ',text)
Línea 29: Almacenamos en placa
el área donde está presente la matrícula, de la imagen en escala de grises.
Debo decir que realicé pruebas tanto con imágenes binarias de placas, así como en grises, y con la segunda obtuve un mejor reconocimiento de caracteres (en este caso), es por ello que en este tutorial tomo el área de la placa en la imagen en escala de grises.
Línea 30: Como ya tenemos la región de interés lista aplicaremos pytesseract.image_to_string
, como primer argumento estará placa
, mientras que el segundo corresponde al modo de segmentación de página config='--psm 11'
. ¿Qué quiere decir esto?, te dejo a continuación una lista de los modos de segmentación de página que soporta tesseract (Si pruebas con otros, el resultado de reconocimiento de caracteres puede cambiar).

Lista de modos de segmentación de página compatibles con tesseract (Fuente)
Línea 31: Imprimimos la informacion obtenida luego de aplicar tesseract a la placa.
1.4 Finalmente, ¡visualización!
cv2.imshow('PLACA',placa) cv2.moveWindow('PLACA',780,10) cv2.rectangle(image,(x,y),(x+w,y+h),(0,255,0),3) cv2.putText(image,text,(x-20,y-10),1,2.2,(0,255,0),3) cv2.imshow('Image',image) cv2.moveWindow('Image',45,10) cv2.waitKey(0)
Línea 33: Visualizamos la placa detectada.
Línea 34: Con cv2.moveWindow
, indicamos que la ventana PLACA
se visualice en la posición (780,10)
de la pantalla.
Línea 35: Dibujamos un rectángulo que rodeará a la placa, para ello usamos la información obtenida en la línea 19.
Línea 36: Visualizamos la información obtenida de la línea 30.
Línea 38 a 40: Visualizamos la imagen contenida en image
, luego hacemos que la ventana correspondiente a esta imagen se ubique en la posición (45,10)
de la pantalla, y finamente usamos cv2.waitKey(0)
para visualizar hasta que cualquier tecla sea presionada.
Programa completo
import cv2 import pytesseract pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract' placa = [] image = cv2.imread('auto001.jpg') gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) gray = cv2.blur(gray,(3,3)) canny = cv2.Canny(gray,150,200) canny = cv2.dilate(canny,None,iterations=1) #_,cnts,_ = cv2.findContours(canny,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE) cnts,_ = cv2.findContours(canny,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE) #cv2.drawContours(image,cnts,-1,(0,255,0),2) for c in cnts: area = cv2.contourArea(c) x,y,w,h = cv2.boundingRect(c) epsilon = 0.09*cv2.arcLength(c,True) approx = cv2.approxPolyDP(c,epsilon,True) if len(approx)==4 and area>9000: print('area=',area) #cv2.drawContours(image,[approx],0,(0,255,0),3) aspect_ratio = float(w)/h if aspect_ratio>2.4: placa = gray[y:y+h,x:x+w] text = pytesseract.image_to_string(placa,config='--psm 11') print('PLACA: ',text) cv2.imshow('PLACA',placa) cv2.moveWindow('PLACA',780,10) cv2.rectangle(image,(x,y),(x+w,y+h),(0,255,0),3) cv2.putText(image,text,(x-20,y-10),1,2.2,(0,255,0),3) cv2.imshow('Image',image) cv2.moveWindow('Image',45,10) cv2.waitKey(0)
Resultados
Luego de todo este procedimiento, obtenemos lo siguiente:

Figura 8: Identificación de la placa vehicular, junto a la imagen de la placa
En la figura 8 muestra la imagen de salida, en la que podemos ver como se ha encontrado exitosamente la placa, además de los caracteres que aparecene en ella.
He probado también con otras imágenes que encontré navegando por internet, y esta vez son imágenes reales, veamos los resultados:

Figura 9: Resultados al aplicar el programa sobre imágenes reales.
En los autos de las imagenes de la parte superior de la figura 9 hemos obtenido realmente buenos resultados, sin embargo si nos fijamos en los autos de la parte inferior en especial en la ‘Q’, tenemos que el carro de la izquierda si se pudo identificar, sin embago en el auto de la derecha en vez de «Q» hemos obtenido «0», además si notas el último dígito es 0, pero dado a que tiene un vacío en la parte superior derecha ha sido reconocido como un ‘6’.
En otras también probadas, a pesar de que se detectaban muy bien las placas, al aplicar OCR no obtenía ningún caracter u obtenía caracteres totalmente diferentes. Te recomiendo realizar muchas pruebas de funcionamiento ya que el reconocimiento de caracteres podría fallar.
Dado que este programa no está realizado con machine learning, es más propenso a que falle ante cambios de iluminación, ángulo de vista, entre otros a menos que, puedas controlar el ambiente donde trabaje. Y bien, espero que este tutorial sirva para repasar el contenido visto en anteriores publicaciones y también espero que te hayas divertido mucho. Nos vemos en un siguiente tutorial de visión por computador.
Excelente videos y blog. Gran explicación de tu parte.
Me gustaría saber si estás e un tutorial de contar objeto específico ya sea cajas, bolsas, etc, que crucen una línea frontera.
Los tutoriales que he visto son de conteo de gente o autos y no cajas o bolsas o algún otro objeto.
Muchas gracias por tu dedicación a los tutoriales
Hola Nel, tienes imágenes o video para analizarlo?
Como puedo implementar con camaras ips ?
Que pueda leer placas de dia y de noche.
Una thread o multiproceso…nose
Hola developer, hasta el momento no he empleado cámaras IPS, en cuanto lo haga subiré algún video tutorial.
Hola! Muy bueno tu artículo y video, todo muy claro y conciso!
Se que hay mucho de «fine tunning» para que se pueda adaptar a patentes de otros países, pero es posible hacerlo.
Tengo dos consultas si las pudieses responder:
a) Que sucede si la foto es tomada lateralmente o desde una mayor altura? Eso es adaptable en el programa? Lo pregunto porque eso podría (tal vez no) crear problemas cuando usas la relación de aspecto para encuadrar la patente.
b) Esto es adaptable a tiempo real? O sea, que se esté tomando la imagen con una cámara de video conectada a un Raspberry y que cuando el vehículo pasa por una marca o barrera imaginaria captura la imagen automáticamebte para luego analizarla?
Muchas gracias!!
Hola Norberto, muchas gracias. En realidad pienso que se podría usar el algoritmo siempre y cuando las condiciones del ambiente estén controladas en lo que más se pueda. Por ejemplo si se ubica la cámara en otro lugar y no de frente al auto podrían haber dificultades e incluso para ese caso sería mejor usar otro tipo de algoritmos, tal vez ya integrar machine learning. Para poder aplicar el proceso en tiempo real se debería antes probar su funcionamiento en el escenario en donde fuera a trabajar y también es muy importante el hardware.
Buenas buen video, pero tengo una consulta, a mi me sale igual el carro rojo con los caracteres pero con 2 signos de interrogacion de mas en el texto, y en la ejecucion me sale un cuadrado al final
area= 9007.0
PLACA: CVL 657 18
■
Gracias por la información nos ayudas bastante
Buenas buen video, pero tengo una consulta, a mi me sale igual el carro rojo con los caracteres pero con 2 signos de interrogacion de mas en el texto, y en la ejecucion me sale un cuadrado al final
area= 9007.0
PLACA: CVL 657 18
■
Gracias por la información nos ayudas bastante
Hola Mario, al parecer es por la nueva versión de pytesseract. En versiones previas no se obtenía ese cuadradito al final.
Hola, queria saber si es posible ignorar ese cuadradito al final, ya que necesito filtrar por texto y esto me trae problemas. Gracias de antemano. saludos
Hola Paula no entiendo muy bien, qué cuadradito final?
Un caracter que no pertenece a la cadena de texto detectado. Ya pude solucionarlo eliminando los dos ultimos caracteres de mi cadena. Gracias! Saludos
Buenos días Gabriela, lo primero quería darte la enhorabuena por este blog tan bueno que estas haciendo. Me parece que haces cada post muy entretenido y además muy educativo gracias a que es muy practico. Por otro lado, estoy realizando un trabajo donde intento detectar semaforos dentro de una imagen, es decir yo tomo una imagen en un paso de cebra con semaforo y quiero elaborar un codigo capaz de eliminar el fondo y solo quedarme con el semaforo. Podrías recomendarme como hacerlo?.
Un cordial saludo,
David
Hola David, muchas gracias. Pienso que podrías analizar si el semáforo es diferenciable del fondo. Si lo es, podrías usar umbralización simple, canny o detección de color por ejemplo para obtener una imagen binaria que en blanco represente la presencia del semáforo en la imagen.
Hola Gabriela,
Primero que todo, dejame felicitarte por tu tu trabajo, muy didactico y entretenido.
He seguido este tutorial y me ha funcionado de maravilla, dejame contarte que lo estoy tratando de usar con mis camaras de vigilancia pero no he podido tener un buen resultado, por ahora me está entregando el siguiente mensaje de error:
[h264 @ 00000143bfa99b80] error while decoding MB 55 33, bytestream -10
[h264 @ 00000143bf51c680] error while decoding MB 33 39, bytestream -5
[h264 @ 00000143bf51c680] left block unavailable for requested intra mode
[h264 @ 00000143bf51c680] error while decoding MB 0 40, bytestream 352
[h264 @ 00000143bf51bf40] error while decoding MB 11 41, bytestream -5
[h264 @ 00000143bfa2c200] left block unavailable for requested intra mode
[h264 @ 00000143bfa2c200] error while decoding MB 0 41, bytestream 2529
[h264 @ 00000143bf51bf40] error while decoding MB 48 30, bytestream -5
[h264 @ 00000143bfa2c200] error while decoding MB 9 35, bytestream -5
[h264 @ 00000143bfa99b80] error while decoding MB 46 35, bytestream -8
Un gran abrazo y muchas felicidades
Hola Cristian, me alegra mucho que te guste el trabajo que hago! De verdad gracias. Estás usando cámaras IP? No he tenido ese error anteriormente.
Hola buenas y buen trabajo. Me preguntaba si se puede hacer un sistema igual leyendo de un video la matricula. En vez de una foto. Gracias.
excelente trabajo, y con un grado de explicites inigualable, gracias Srita. Gaby.
Me pregunto si puedo utilizar la misma codificación para usar un raspberry. Y también me pregunto como pudiera utilizar una camara ip para esto…
Si fuese tan amable de orientar a su servidor, estaría fascinado con usted.
De antemano gracias por compartir.
Hola José, claro que puedes realizarlo en la raspberry pi. Lo que tendrías que hacer es instalar todos los paquetes necesarios en la raspberry. En cuanto a la cámara, si mal no recuerdo en las últimas versiones de OpenCV se podía llamar a la cámara como cualquier otra, no era necesario realizar una configuración extra. 🙂
Buenos dias,
Muchas gracias por tu gratitud y trabajo, me encanta.
Una pregunta, se podria adaptar este codigo con camaras ip
Gracias
Hola Jesús, si podrías hacerlo. Tendrías que indicarle a OpenCV la cámara del video a leer especificando su url.
Perdona pero no soy muy lucho, podrias indicarme como.
Muchas gracias por anticipado
Hola, tengo q hacer la prueba y luego ver como lo hago para recibir desde cámaras públicas, me gustaría hacer un proyecto para captar patentes de motos con base de datos de denuncias de robo. Gracias por «regalarnos» tu conocimiento y tu tiempo.
Saludos desde Argentina…
Muchas gracias Omar, eres muy amable. 🙂 Saludos para ti también.
Hola Gaby, quiero agradecerte por tus videos, son de mucha ayuda tanto para los estudiantes como para las personas que les interesa el mundo de visión por computador…
ahora respecto al tema… me gustaría poder realizar el reconocimiento de placas pero con autos en movimiento. No se si podrias darme una mano con eso porfa… 🙂
Hola Fernando, muchas gracias. Podrías realizar un proceso similar, tratando de tener un ambiente controlado, ya que si hay cambios de iluminación, fondo desordenado, entre otros, tendrías que optar por otro algoritmo para extraer la placa, y luego los caracteres de ella.
Hola Gaby, saludos desde Colombia, podrías compartirnos las demás imágenes con las que hiciste las pruebas para probarlas en el programa y si tal vez hay alguna forma de que la programación que concluiste pueda detectar de la misma manera con imágenes de placas del buscador de google, muchas gracias por regalarnos conocimiento eres super crack
Hola, muy bueno el tutorial pero tenía una duda aparte del tema de este blog, se podría aplicar algo parecido para extraer únicamente algún carácter en específico de una imagen? por ejemplo, si tengo un código hexadecimal y que de ahí solo quiera extraer el #, la B y la C (por ejemplo) se puede hacer con algo parecido a lo de este blog o es totalmente distinto?
Hola Sadaga, depende del área o ambiente de donde desees obtener los caracteres. Podrías hacer una whitelist, para solo detectar ciertos caracteres.
Hola Omesitos, he estado intentando con un streaming, dibujando la placa en un papel xd.
El código esta en algo, si que debe tener buena iluminación y estar muy bien pintado.
Espero les sirva,
solo copien y descomentan en su editor.
Con fe!
# from multiprocessing.connection import wait
# import cv2
# import pytesseract
# placa = []
# capture = cv2.VideoCapture(0)
# while capture.isOpened():
# ret, frame = capture.read()
# if ret == False:
# break
# captureGray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# # Aplicamos cv2.blur para disminuir el ruido que pueda presentar la imagen,
# captureGray = cv2.blur(captureGray, (4, 4))
# canny = cv2.Canny(captureGray, 100, 200)
# canny = cv2.dilate(canny, None, iterations=1)
# ctns, _ = cv2.findContours(canny, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
# cv2.imshow(‘canny’, canny)
# for c in ctns:
# # Determinando el área de los contornos
# area = cv2.contourArea(c)
# # Usamos la función cv2.boundingRect para obtener los puntos x, y el ancho y alto del contorno actual
# x, y, w, h = cv2.boundingRect(c)
# # Es el parámetro que especifica la precisión de aproximación.
# epsilon = 0.07*cv2.arcLength(c, True)
# # Dicho de otro modo, imprimirá la cantidad de vertices de cada contorno que esté analizando
# approx = cv2.approxPolyDP(c, epsilon, True)
# # Encontrar el rectángulo de la matrícula 9000 | and area > 70000 and area 25000 and area 1.2:
# # Almacenamos en placa el área donde está presente la matrícula, de la imagen en escala de grises.
# placa = captureGray[y:y+h, x:x+w]
# # Como ya tenemos la región de interés lista aplicaremos pytesseract.image_to_string,
# # 1. Como primer argumento estará placa,
# # 2. Mientras que el segundo corresponde al modo de segmentación de página config=’–psm 11′
# text = pytesseract.image_to_string(placa, config=’–psm 11′)
# print(‘PLACA’, text)
# cv2.imshow(‘PLACA’, placa)
# cv2.moveWindow(‘PLACA’, 780, 10)
# cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 3)
# cv2.putText(frame, text[:-2],
# (x-20, y-10), 1, 2.2, (0, 255, 0), 2)
# if cv2.waitKey(1) & 0xFF == ord(‘s’):
# break
# cv2.imshow(‘frame’, frame)
# capture.release()
# cv2.destroyAllWindows()
——————-
Saludos Gabriela.
Pensé que iba a mantener el orden, comentando todo el código jajaja, con fe x2.
hola lo intente con tu codigo pero no se abre la pantalla de la camara o estoy haciendo algo mal me podrias ayudar en esa parte porfavor
Hola, me encanta tu canal he aprendido mucho, queria saber si me puedes guiar para llamar a una camara IP, estoy haciendo un proyecto donde se me pueda detectar a la placa infractora por restriccion vehicular. muchas gracias y sigue adelante con tu contenido
Hola gracias por todo esta bien explicado pero te comento que intente usar la cámra ip de mi sistema de seguriad para leer la placa patente de mi vehiculo pero no fue posible me entrega la imagen pero no es capas de leer o identificar. necesito algun comentario de ayuda porfavor gracias
import cv2
import pytesseract
import numpy as np
# Configura el path al ejecutable de Tesseract en tu sistema
pytesseract.pytesseract.tesseract_cmd = r’C:\Program Files\Tesseract-OCR\tesseract.exe’
# URL de transmisión de la cámara IP
url = «rtsp://admin:admin@10.10.8.6:554/cam/realmonitor?channel=1&subtype=0»
placa = cv2.VideoCapture(url)
while True:
# Lee el video de la cámara IP
ret, frame = placa.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray = cv2.blur(gray, (3, 3))
canny = cv2.Canny(gray, 150, 200)
canny = cv2.dilate(canny, None, iterations=1)
cnts, _ = cv2.findContours(canny, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
for c in cnts:
area = cv2.contourArea(c)
x, y, w, h = cv2.boundingRect(c)
epsilon = 0.09 * cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, epsilon, True)
if len(approx) == 4 and area > 9000:
aspect_ratio = float(w) / h
if aspect_ratio > 3: #la placa mide 370x120mm matricula chilena
placa = gray[y:y + h, x:x + w]
text = pytesseract.image_to_string(placa, config=’–psm 13′)
print(‘PLACA: ‘, text)
cv2.imshow(‘PLACA’, placa)
cv2.moveWindow(‘PLACA’, 780, 10)
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 3)
cv2.putText(frame, text, (x – 20, y – 10), 1, 2.2, (0, 255, 0), 3)
cv2.imshow(‘Reconocimiento de placas’, frame)
cv2.moveWindow(‘Reconocimiento de placas’, 45, 10)
# Rompe el bucle si se presiona la tecla ‘q’
if cv2.waitKey(1) & 0xFF == ord(‘q’):
break
# Libera los recursos y cierra las ventanas de visualización
placa.release()
cv2.destroyAllWindows()
Hola Gabriela, este proyecto lo has hecho en Android con tesseract?
Gracias
Hola John, ¿cómo estás?. Contestando a tu pregunta, en realidad no. No he desarrollado proyectos de visión por computador en Android.
Estoy teniendo un problema con el codigo tal cual lo indicas, me abre la imagen de la cual tiene que detectar la patente pero no hace nada se queda alli, alguna idea que puede estar sucediendo?
Saludos y gracias!
Hola Gaby muchas gracias por el video me encanto mucho, estoy empezando a programar en python y la verdad q me ayuda mucho. te consulto algo: a pesar que puse el codigo tal cual lo escribistes en el video, no me muestra la imagen q descargue de un auto. Puede ser q no me este lebantando el archivo de la imagen? en tal caso, como podria hacerlo. Muchas gracias por tu ayuda.