2012-01-02 15 views
8

Estoy escribiendo una aplicación de OCR para leer caracteres de una imagen de captura de pantalla. Actualmente, me estoy enfocando solo en los dígitos. Estoy basando parcialmente mi enfoque en esta publicación de blog: http://blog.damiles.com/2008/11/basic-ocr-in-opencv/.OCR de texto de baja resolución de capturas de pantalla

Puedo extraer con éxito cada carácter individual usando algunos umbrales inteligentes. Donde las cosas se ponen un poco complicadas es hacer coincidir los personajes. Incluso con el tamaño y la fuente de fuente fija, existen algunas variables como el color de fondo y el interletraje que hacen que aparezca el mismo dígito en formas ligeramente diferentes. Por ejemplo, la imagen de abajo se divide en 3 partes:

  1. Top: un dígito objetivo que extraje con éxito de una captura de pantalla
  2. Medio: la plantilla: un dígito de mi conjunto de entrenamiento
  3. En pocas palabras: la error (diferencia absoluta) entre las imágenes superior e intermedia

Todas las partes han sido escaladas (la distancia entre las dos líneas horizontales verdes representa un píxel).

topbottommiddle

se puede ver que a pesar de la parte superior e imágenes secundarias que representa claramente un 2, el error entre ellos es bastante alto. Esto causa falsos positivos al hacer coincidir otros dígitos; por ejemplo, no es difícil ver cómo un 7 bien ubicado puede hacer coincidir el dígito objetivo en la imagen superior mejor que la imagen del medio.

Actualmente, estoy manejando esto teniendo un montón de imágenes de entrenamiento para cada dígito, y haciendo coincidir el dígito de destino con esas imágenes, uno a uno. Traté de tomar la imagen promedio del conjunto de entrenamiento, pero eso no resuelve el problema (falsos positivos en otros dígitos).

Soy un poco reacio a realizar coincidencias usando una plantilla desplazada (sería esencialmente lo mismo que lo que estoy haciendo ahora). ¿Hay una mejor manera de comparar las dos imágenes que la simple diferencia absoluta? Estaba pensando en algo como el EMD (distancia de movimiento de tierra, http://en.wikipedia.org/wiki/Earth_mover 's_distance) en 2D: básicamente, necesito un método de comparación que no sea tan sensible al cambio global y pequeños cambios locales (los píxeles al lado de un píxel blanco se vuelven blancos , o píxeles junto a un píxel negro que se vuelve negro), pero es sensible a los cambios globales (los píxeles negros que no están cerca de los píxeles blancos se vuelven negros, y viceversa).

¿Alguien puede sugerir un método de coincidencia más efectivo que la diferencia absoluta?

Estoy haciendo todo esto en OpenCV utilizando las envolturas Python C-style (import cv).

Respuesta

6

Me gustaría investigar el uso de cascadas Haar. Los he usado para la detección de rostros/seguimiento de la cabeza, y parece que podrías construir un conjunto bastante bueno de cascadas con suficientes "2", "3", "4", y así sucesivamente.

http://alereimondo.no-ip.org/OpenCV/34

http://en.wikipedia.org/wiki/Haar-like_features

+0

Gracias! Definitivamente voy a echar un vistazo a las cascadas de Haar. ¿Qué tan eficiente crees que será comparado con la simple resta de imágenes? Espero que sea más lento. Sin embargo, si es 5 veces más lento pero reemplaza 10 controles de imagen por la misma efectividad, definitivamente valdría la pena. – misha

+0

Tendrá que generar cascadas, que es un proceso bastante lento (pero también estúpidamente paralelizable). También requiere un montón de datos de entrada (usaría los números en cada fuente que tenga en un escritorio). – rsaxvc

+0

Más lento que la resta, pero puede buscar una imagen para todas las instancias de una determinada cascada a la vez. – rsaxvc

3

OCR en imágenes con ruido no es fácil - enfoques tan simple no no funcionan bien.

Así que, le recomendaría usar HOG para extraer las características y SVM para clasificar. HOG parece ser una de las formas más poderosas de describir formas.

Todo el proceso de canalización se implementa en OpenCV, sin embargo, no conozco los nombres de las funciones en los wrappers de Python. Debería ser capaz de entrenar con la última haartraining.cpp (en realidad es compatible con algo más que haar), HOG y LBP también.

Y creo que el último código (desde el enlace troncal) ha mejorado mucho con respecto a la versión oficial (2.3.1).

HOG generalmente necesita solo una fracción de los datos de entrenamiento utilizados por otros métodos de reconocimiento, sin embargo, si desea clasificar formas que están parcialmente ocluidas (o que faltan), debe asegurarse de incluir algunas de estas formas en el entrenamiento.

+0

No llamaría a las imágenes * ruidosas * per se, pero veo de dónde vienes. Echaré un vistazo a HOG. Gracias. – misha

3

Por mi experiencia y por leer varios artículos sobre clasificación de caracteres, puedo decir que una buena forma de comenzar es leyendo el Análisis de componentes principales (PCA), el Análisis discriminante lineal de Fisher (LDA) y las Máquinas de vectores de soporte (SVM). Estos son métodos de clasificación que son extremadamente útiles para OCR, y resulta que OpenCV ya incluye implementaciones excelentes en PCAs y SVMs. No he visto ningún ejemplo de código OpenCV para OCR, pero puede usar alguna versión modificada de la clasificación de caras para realizar la clasificación de caracteres. Un recurso excelente para el código de reconocimiento facial para OpenCV es this website.

Otra biblioteca para Python que te recomiendo es "scikits.learn". Es muy fácil enviar cvArrays a scikits. Aprender y ejecutar algoritmos de aprendizaje automático en sus datos. Un ejemplo básico para OCR que usa SVM es here.

Otro ejemplo más complicado que utiliza el aprendizaje múltiple para el reconocimiento de caracteres escritos a mano es here.

Cuestiones relacionadas