(nuevo) lector de código de tortillas

publicado el 2018-09-01

parte del proyecto: tortilla-stories


después de que mel hiciera unas pruebas pintando en las tortillas, y evaluando el área disponible en ellas, reconsideramos el uso de los códigos qr, al fin todavía no estaba terminado ese sistema.

surgió la idea de, aprovechando las ideas anteriores de marcadores, usar una secuencia binaria de puntos sobre una línea recta imaginaria. remitiéndonos a las notas sobre marcadores con la implementación de visión computacional “tradicional”, se podría decir que esta es una mezcla entre la idea de la línea a detectar con hough, con la idea de los cuatro marcadores o la lectura rotacional.

más que nada vimos que estéticamente quedaba bien y no interfería con los dibujos como tal vez sí lo harían los códigos qr.

secuencia intercalada de círculos negros sobre un fondo claro: 1 0101 1011 0 1

ejemplo del código para el número 91...

la misma imagen pero con indicadores que dan a entender las posiciones de los centros de los círculos que están en cero (no pintados)

... y cómo se ve al ser leído (0101 1011)

descripción del sistema

esta lista describe las características del sistema para los códigos:

  • hay un área rectangular activa donde se realizará la lectura de una tortilla
  • la línea imaginaria del código no necesariamente tiene que coincidir con el rectángulo
  • el sistema permite una variedad suficiente de combinaciones (256)
  • el sistema tiene formas de prevenir lecturas erróneas por ruido o códigos no completamente en el área activa
  • el código será pintado a mano utilizando un estencil, por lo que el sistema no debe requerir precisión milimétrica

el protocolo para el código

estas son las características del código al que llegué de acuerdo a las necesidades:

  • consiste en una secuencia de once espacios circulares, separados entre ellos por un margen de dos terceras partes su diámetro
  • el diámetro de estos espacios ha de ser lo suficientemente grande para poderlos diferenciar por tamaño después de filtrar la imagen original
  • los espacios circulares pueden estar pintados con tinta negra / oscura (“uno”) o sin pintar (“cero”), por lo que se comportan como bits.
  • los espacios en los extremos siempre van en “uno”, para señalar que el mensaje está contenido entre ellos
  • de los nueve espacios restantes, ocho son los bits del mensaje como tal, y uno funciona como bit de paridad.
  • los ocho bits del mensaje se comportan como un byte que se lee de izquierda a derecha (más significativo a la izquierda)
  • el bit de paridad es “uno” cuando la cantidad de “unos” en el mensaje es una cantidad par, y es “cero” cuando es una cantidad impar. (probablemente esta sea la forma más rudimentaria de checksum para corroborar la integridad del mensaje; básicamente este comportamiento hace que la cantidad de “unos” en los nueve bits de mensaje + paridad siempre sea impar si todo está bien)
rata panchis con una laptop y una especie de regadera (cámara) apuntando a una tortilla

parecía sencillo esto de leer tortillas...

algoritmo de detección e identificación

básicamente, el programa que construí realiza el siguiente algoritmo:

  • dentro del área rectangular activa, usa un umbral de brillo, [probablemente utiliza erosión para eliminar partículas pequeñas] y detecta los contornos que están presentes en la imagen
  • encuentra el contorno que está más a la izquierda (x menor) y el que está más a la derecha (x mayor)
  • calcula el vector o línea que pasa del centro del primero al centro del segundo
  • divide esa línea en diez partes iguales para obtener las posiciones esperadas de los centros de los espacios circulares del mensaje + paridad.
  • por cada uno de esos centros, añade un punto adyacente; corrobora si ambos a la vez están adentro de algún contorno.
    • si sí, significa que el espacio que corresponde a dicho centro, está en “uno” (está pintado)
    • si no, significa que el espacio que corresponde a dicho centro, está en “cero” (no está pintado)
    • ve tomando nota de cuáles son ceros y unos, tanto para reconstruir el número binario, como para contar cuántos “unos” son y corroborar la paridad.
  • primer chequeo de error: asegúrate que la cantidad de “unos” sea igual a la cantidad de contornos. si no es así es porque o los círculos se empalman de alguna forma, o porque se está considerando como extremos a círculos que no son los extremos en realidad; esto hace que las posiciones sobre la línea se descuadren.
  • segundo chequeo de error: aseguráte que la cantidad de “unos”, contando al bit de paridad, sea una cantidad impar
  • dibuja algunas pistas visuales en el proceso
  • si todo sale bien, el número calculado es probablemente el número que está presente en el código. compara si corresponde al número almacenado previamente, y si no, avisa del cambio.

como un extra a desarrollar: calibración de las medidas esperadas de los círculos y de las líneas.

ejemplo de resultados

fila horizontal de once círculos negros

código para el número 255 en posición alineada

fila horizontal de once círculos negros, con indicaciones superpuestas de los puntos de inicio y fin, y puntos brillantes para indicar los bits en uno

la imagen después de ser procesada sin errores

fila en diagonal de siete círculos negros, separados de manera no regular

ejemplo de código inclinado pero dentro del área activa

la misma imagen pero con indicadores que dan a entender las posiciones de los centros de los círculos que están en cero (no pintados)

al ser procesada, el número obtenido es 91 (0101 1011) con bit de paridad en 0

fila en diagonal de once círculos negros, separados de manera regular pero algunos de ellos están parcialmente fuera del área activa

ejemplo de código saliéndose del área activa

la misma imagen pero con los indicadores sobrepuestos, los centros esperados de los círculos no coinciden con los centros de los círculos

los círculos incompletos no son detectados como contornos independientes, por lo que al usar los contornos que quedan a los extremos, el sistema se desalinea y marca un error

fila de 6 círculos negros separados de manera no regular

¿todo bien con este código?

la misma imagen pero con los indicadores sobrepuestos, nada se ve fuera de lo normal

aquí la paridad es incorrecta, a los cuatro bits del mensaje les correspondería un 1 en el bit de paridad - el sistema aquí marca un error

secuencia inclinada de siete círculos con diferentes tamaños

¿qué pasa con círculos irregulares?

la misma imagen pero con los indicadores, a pesar de las diferencias de tamaño, siguen alineados

las diferencias de tamaño no son suficientes, por lo que el sistema sigue funcionando y puede detectar al número 74 (1010 1110) con un bit de paridad en 0

descarga el programa

todo el comportamiento sucede en una clase “lector”, que implementé en un pequeño programa “lector_codigo_tester” que comparto aquí en una carpeta zip.

puedes cambiar el número de imagen de prueba para ver los resultados en la consola (número encontrado, secuencia binaria, cantidad de unos, errores encontrados, etc)

ahora toca ir juntando los bloques funcionales… ya estaré reportando :D