El libro de cocina de mi abuela se encuentra con el aprendizaje automático parte I
Mi abuela fue una cocinera excepcional. Entonces, cuando recientemente encontré su viejo libro de cocina, traté de leer algunas de las recetas, con la esperanza de poder recrear algunos de los platos que disfruté cuando era niño. Sin embargo, esto resultó más difícil de lo esperado ya que el libro se imprimió alrededor de 1911 en una tipografía llamada f raktur . Desafortunadamente, el tipo de letra fraktur se desvía de los tipos de letra modernos en varios casos. Por ejemplo, la letra “A” parece una “U” en fraktur y cada vez que veo una “Z” en fraktur leo un “3” (ver Figura 2).
Así surgió la idea de desarrollar una tubería que creará una traducción en vivo de la Fraktur letras en una tipografía moderna. Con tal herramienta en la mano, podríamos leer fácilmente las recetas y enfocarnos en la parte de cocinar en lugar de descifrar el libro.
Afortunadamente, existen muchas herramientas excelentes de código abierto que nos ayudarán a desarrollar dicha canalización. Sin embargo, algunos aspectos de este proyecto deben construirse desde cero.
Principalmente necesitamos un conjunto de datos para entrenar nuestros algoritmos de aprendizaje automático. Y esto es en lo que nos centraremos en este artículo.
Pero antes de comenzar con el conjunto de datos, echemos un vistazo rápido a todas las tareas que tenemos por delante:
Detectar letras individuales en una imagen
Crear un conjunto de datos de entrenamiento a partir de estas letras
Entrenar un algoritmo para clasificar las letras
Utilice el algoritmo entrenado para clasificar letras individuales (en línea)
Cubriremos los dos primeros temas de este artículo y continuaremos con los temas 3 y 4 en un segundo y tercer artículo. Esto debería darnos suficiente espacio para explorar cada una de las tareas en detalle.
También como una observación general : en estos artículos no nos centraremos en cómo implementar cada algoritmo desde cero. En cambio, veremos cómo podemos conectar diferentes herramientas para traducir el libro de cocina a una tipografía moderna.
Entonces, la primera tarea es encontrar una manera de extraer letras individuales de las páginas del libro de cocina. Esta es la base de todo lo que sigue. En el siguiente paso, podemos crear un conjunto de datos a partir de las letras extraídas y finalmente entrenar un clasificador en él.
Las entradas a nuestra tubería siempre serán imágenes de páginas del libro de cocina similar al que se muestra en la Figura 3 anterior. Estas entradas pueden ser imágenes individuales de alta resolución de una cámara de teléfono inteligente o una secuencia de imágenes de una cámara web.
Lo que tenemos que asegurar es que cada imagen, independientemente de su origen, se procese de manera que el algoritmo de detección pueda encontrar todas las letras individuales. Lo primero que debe recordar aquí es que las cámaras digitales almacenan imágenes en tres canales separados: R ed, G reen y B lue ( RGB ). Pero en nuestro caso, estos tres canales contienen información redundante ya que las letras se pueden identificar en cada uno de estos tres canales por separado. Por lo tanto, primero convertiremos todas las imágenes a escala de grises.
Como resultado, en lugar de tres canales, solo tenemos que lidiar con un canal. Además, también redujimos la cantidad de datos a 1/3, lo que debería mejorar el rendimiento. Pero nuestro algoritmo de detección enfrentará otro problema: condiciones variables de rayos. Esto complica la separación de las letras del fondo a medida que cambia el contraste en la imagen.
Para resolver esto, utilizaremos una técnica llamada umbral adaptativo que utiliza píxeles cercanos para crear umbrales locales que luego se utilizan para binarizar la imagen. Como resultado, la imagen procesada solo consistirá en píxeles en blanco y negro; no más gris Luego podemos optimizar aún más la imagen para la detección de letras al eliminar el ruido con un filtro de desenfoque medio.
El siguiente código describe una función de Python que realiza la conversión de imágenes de RGB a blanco y negro con la ayuda de la biblioteca openCV . El resultado de este paso de procesamiento se ejemplifica en la Figura 4.
# Defina una función que convierta una imagen en una imagen con umbral
def convert_image (img, blur = 3):
# Convertir a escala de grises
conv_img = cv2.cvtColor (img, cv2.COLOR_BGR2GRAY)
# Desenfoque la imagen para reducir el ruido
conv_img = cv2.medianBlur (conv_img, blur)
return conv_img
Ok ahora que procesamos la imagen es hora de detectar las letras. Para esto, podemos usar el método findContours de la biblioteca openCV . El código se reduce a una sola línea llamada por la función a continuación.
Luego podemos asignar los cuadros delimitadores de los contornos encontrados por esta función nuevamente en la imagen RGB original para ver lo que realmente se detectó (Figura 5).
# Defina una función que detecte contornos en la imagen convertida
def extract_char (conv_img):
# Buscar contornos
_, ctrs, _ = cv2.findContours (conv_img, cv2.RETR_TREE,
cv2.CHAIN_APPROX_SIMPLE)