lunes, 20 de mayo de 2013

Proyecto Final

Reconocimiento de caracteres

Hola a todos mis compañeros y gente que visita mi blog, esta entrada corresponde a mi proyecto final de la materia de visión computacional, consiste en el reporte del mismo y contiene los siguientes temas (establecidos por la maestra, Dra. Elisa Schaeffer):

REPORTE
 
 Propósito / justificación



El propósito de mi proyecto es principalmente para digitalizar documentos que tengamos en papel, esto ahorra tiempo de escritura en el caso de que se vayan a transcribir documentos largos y además evita el trabajo de hacerlo.
Hay que reconocer que el sistema no es perfecto y podrían existir errores en el reconocimiento de algunos caracteres, pero aún así facilita la transcripción de documentos muy largos como la transcripción de libros completos.
De hecho el motor de reconocimiento de caracteres que usé es desarrollado actualmente por google para su proyecto de digitalización de libros (Google books)


 Diseño del software

El software lo dividí en 4 partes que consisten en la entrada de los datos,  preprocesamiento, el reconocimiento y la salida del sistema, a continuación detallo cada una de las tres partes, además de un diagrama que explica el funcionamiento en conjunto:
  • Entrada: La entrada de los datos (las imágenes) las obtengo por medio de la cámara web del ordenador, primero abro la captura de la cámara con la facilidad que provee OpenCv, después capturo una imagen presionando "backspace".
  • Preprocesamiento: Luego de obtener la imagen con el texto a reconocer (fotografía sosteniendo la hoja o el libro a transcribir), abro la imagen dentro de una ventana de OpenCv, después en la misma ventana marco con el mouse en un rectángulo la zona de interés, en este caso el texto a reconocer.
  • Reconocimiento: Después de obtener la nueva imagen con la zona de interes, le paso esta nueva imagen al motor de reconocimiento "tesseract - OCR", en específico uso el método "image_to_string" y este método llama al ejecutable "tesseract" . El método me regresa el texto y simplemente lo almaceno en una variable.
  • Salida del sistema: El resultado entregado por el motor de reconocimiento lo almaceno en un archivo de texto y luego llamo a un shell que realicé para que abriera dicho archivo en un gedit (de esta manera le facilito la tarea al usuario).



 Librerías utilizadas


Las librerías que yo utilicé fueron pytesser, os, PIL, OpenCV, pyscreenshot, entre otras, a continuación describiré para qué utilicé cada una de ellas.
from pytesser import * 
import os
import Image
import cv2.cv as cv
import pyscreenshot as ImageGrab
from PIL import *



  • PyTesser: Utilicé el motor "tesseract - OCR" de pytesser para realizar el reconocimiento de los caracteres presentes en una imagen (la imagen la obtuve de la cámara web). Pytesser cuenta con diversos módulos de reconocimiento, yo utilicé el método Image_to_string para obtener la cadena reconocida. El motor de reconocimiento de caracteres "tesseract" es actualmente desarrollado por Google, y usado por ellos mismos en su proyecto "Google Books"; inicialmente tesseract fue desarrollado por la compañía HP.
  • Os: El módulo os lo utilicé para poder emplear funciones del sistema operativo, por medio del módulo os abrí un shell que a su vez abre gedit con mi archivo de texto de salida dentro.
  • PIL: El módulo de Python Image Library lo usé para cargar las imágenes con las que trabajé, además de tener un fácil acceso a cada uno de los píxeles y dimensiones de las mismas. Al tener acceso a los pixeles de las imágenes pienso realizar futuros filtros para quitar ruidos y manchas que impiden el correcto reconocimiento.
  • OpenCV: El módulo de OpenCV lo usé para cargar la funcionalidad de cámara web y también para aplicar los filtros de escala de grises y binarización a las imágenes obtenidas, con el fin de presentar imágenes más sencillas y "fáciles" de reconocer por el motor "tesseract - OCR".
  • Pyscreenshot: Este módulo lo usé para poder cortar sobre la imagen obtenida de la cámara web el aŕea de interés del usuario. Tomando en cuenta que no todo lo que está presente en el docuemento es relevante (por ejemplo, dibujos, gráficas, etc).
 Descripción textual y diagramas de los algoritmos desarrollados


Entrada del sistema: 

La entrada del sistema la realizo por medio de la cámara web. Al iniciar el programa abro la ventana de la cámara web para que el usuario ponga a la vista de la cámara el documento en papel, luego por medio de la tecla "backspace" el usuario captura la imagen para pasar al módulo de cortado de la imagen. A continuación una imagen del proceso.


Cortar contenido relevante: 

Para obtener solo el contenido relevante de la imagen o del documento en papel del usuario realicé un módulo que te permite cortar la imagen por medio de mouse, eliminando de la imagen fotografías, imágenes o gráficas que no nos interesan (o que no puede procesar el algoritmo de reconocimiento de caracteres). A continuación una imagen del proceso.



Escala de grises y binarización:

Para presentarle al motor de reconocimiento de caracteres "tesseract - OCR" imágenes más sencillas de reconocer, primero paso por escala de grises y binarización la imagen, ya que obtenía mucho mejores resultados después de correr estos fitros (para esto hice uso de OpenCV). En un futuro tengo pensado implementar más filtros, como un limpiador para quitar ruido de la imagen. A continuación una imagen del proceso:




Salida del sistema:

Para finalizar uso el módulo PyTesser para el reconocimiento de los caracteres, el módulo PyTesser cuenta con distintos métodos para distintas funcionalidades, en mi caso usé el método Image_to_String, que, después de pasarle como parámetro mi imagen previamente filtrada, el método llama al ejecutable tesseract.exe que es el que se encarga del reconocimiento. Luego me entrega la cadena de caracteres que guardo en un archivo de texto. Después de esto, por medio de la librería "os" mando llamar a un shell que se encarga de abrir gedit con mi archivo de texto titulado "salida.txt" (para mayor facilidad y comodiad al usuario). A continuación una imagen del proceso.



Si comparamos con la imagen de entrada, podemos notar que solamente hubo un error, pero conforme disminuía el tamaño de las letras del documento naturalmente se presentaban más errores, esto lo compruebo más adelante en la evaluación del desempeño.



(Demostración de funcionamiento, recomendable ponerlo en fullscreen)

Pruebas con distintas imágenes(distinto contenido y tamaño de fuente)

Bien, para realizar las pruebas del algoritmo de reconocimiento de caracteres (tesseract - OCR) utilicé 4 distintas imágenes; distintas referente al contenido y al tamaño de la fuente. Lo que se podía apreciar a simple vista es que el algoritmo de reconocimiento batallaba más conforme iba reduciendo el tamaño de la fuente de los documentos.
Para poder reconocer cada una de las palabras en los textos de fuentes pequeñas necesité acercar demasiado el documento a la cámara web, pero aún así los caracteres resultaban demasiado pequeños para el algoritmo, y el reconocimiento era bastante defectuoso, o de plano no se realizaba el reconocimiento.


A continuación les muestro las imágenes de entrada, los pasos de procesamiento y las salidas de cada uno de los 4 documentos. Comencé realizando las pruebas con documentos de tamaño de fuente grande (tamaño 25), luego fui decrementando el tamaño de 5 en 5 hasta llegar a 10 (todos los documentos escritos en letra Arial).


Prueba 1 - Tamaño de fuente 25.


(Imagen capturada mediante la webcam) 


(Imagen recortada y binarizada)




(Salida del algoritmo de reconocimiento de caracteres)



Prueba 2 - Tamaño de fuente 20.

(Imagen capturada mediante la webcam) 


(Imagen recortada y binarizada)


(Salida del algoritmo de reconocimiento de caracteres)


Prueba 3 - Tamaño de fuente 15.

(Imagen capturada mediante la webcam) 



(Imagen recortada y binarizada)



(Salida del algoritmo de reconocimiento de caracteres)


Prueba 4 - Tamaño de fuente 10.
 
(Imagen capturada mediante la webcam) 


(Imagen recortada y binarizada, son pocas palabras porque tuve que acercar demasiado el documento a la cámatra web, de otra manera, el algoritmo no reconocía nada)



(Salida del algoritmo de reconocimiento de caracteres)



Evaluación de desempeño

Para realizar la evaluación del desempeño realicé una gráfica con los errores y aciertos cometidos durante la detección de los caracteres, para hacer las pruebas tomé 4 documentos con contenido distinto y también con tamaño de fuente distinto. 
Usé los tamaños de fuente 10, 15, 20 y 25, todos a fuente Arial.




El algoritmo de reconocimiento de caracteres "tesseract" tuvo un mayor número de aciertos con el documento de fuente tamaño 20, pero esto no quiere decir que el tamaño de fuente sea el ideal o el que mayores aciertos tiene sobre todos, sino que debemos recordar que cada documento tenía distinto número de palabras y distinto contenido. En todo caso el documento con el que se ovtuvo mayor acierto fue el de tamaño de fuente 25, naturalmente. También esto explica la cantidad de errores con el tamaño de fuente 10, ya que el número de palabras a reconocer solo fue de 17, porque eran tan pequeñas las letras que tuve que acercar demasiado el documento a la cámara.

A partir del número de fuente 15, los errores eran tantos que el texto parecía escrito en alemán :). 

Trabajo a futuro (mejoras e ideas)

El trabajo a realizar a futuro es desarrollar nuevos filtros para presentar una mejor entrada al motor de reconocimiento de caracteres "tesseract - OCR". Entre los filtros que pienso desarrollar son un limpiador de imágenes, que quite todo el ruido que impide el corrector reconocimiento. 




Además de una filtro que corrija el ángulo de documento, ya que por medio de la cámara web, es bastante propensa la mala colocación del documento, impidiento el correcto reconocimiento.


A continuación les dejo con la presentación que expuse en clase:




CÓDIGO
 

- Control de versiones (liga al repositorio): https://github.com/eddypre/TrianaVisionProject

- Comentarios: Las funciones más relevantes de mi código están comentarizadas para su fácil entendimiento.
 
- README & INSTALL: Agregué en el repositorio 2 archivos de texto un README y un INSTALL que muestran los pasos para correr el programa y también para instalar las librerías necesarias, respectivamente.

- Ejemplos (datos): En el repositorio se encuentran los archivos de texto con las salidas de cada imagen tomada por la cámara web, se trata de 4 imágenes con distinto contenido y con distinto tamaño de letra (tamaño 5, 10, 15 y 20. Todos con fuente Arial).


BIBLIOGRAFÍA

- Creación, carga y lecturas de archivo de texto, [Web en línea]. <http://pythonya.appspot.com/detalleconcepto?deta=Creaci%C3%B3n,%20carga%20y%20lectura%20de%20archivos%20de%20texto>. [Consulta: 25-03-13]
- Converting image with Python + OpenCV, [Web en línea]. <http://extr3metech.wordpress.com/2012/09/23/convert-photo-to-grayscale-with-python-opencv/>. [Consulta: 25-03-13]

- Converting an OpenCV Image to black and white, [Web en línea]. <http://stackoverflow.com/questions/7624765/converting-an-opencv-image-to-black-and-white>. [Consulta: 25-03-13]

- Ubuntu 12.04, the installation PyTesser in OCR recognition, [Web en línea]. <http://www.rapidsnail.com/Tutorial/t/2012/1031/11/21498/ubuntu-1204-the-installation-pytesser-in-ocr-recognition.aspx>. [Consulta: 25-03-13]


Eso es todo por mi parte.

Cualquier duda o aclaración pueden dejarla en la caja de comentarios. 

Saludos a todos! 

2 comentarios:

  1. Se ve todo bien. Van 9 pts por la presentación. En trabajo futura sería bueno contemplar un recorte automático de la zona a procesar.

    ResponderEliminar
  2. Me hubiera gustado conocer los tiempos de ejecución; hay algunas faltas menores de ortografía. 9 pts por el reporte.

    En el README falta identificarte a ti mismo como autor. El código ocuparía comentarios. 8 pts por el repo.

    ResponderEliminar