En nuestra aplicación hay una característica, como el
hijo de Vivino, la
novia de mi madre : la definición de vino a partir de una fotografía. Debajo del capó, el uso de servicios de terceros, Tineye, para determinar la etiqueta más adecuada, Google Vision, para leer el texto en él. Esto último es necesario para aclarar el producto correcto, porque La búsqueda de imágenes no tiene en cuenta la importancia de algunas regiones, por lo general, es información textual, año y tipo de vino.
Sin embargo, la precisión de ambos servicios se reduce notablemente debido al hecho de que la etiqueta está distorsionada por una superficie cilíndrica.
Esto es especialmente notable con Google Vision: cualquier texto fuera de la parte central de la etiqueta es prácticamente ilegible, aunque una persona lo reconoce fácilmente. En este artículo, describiré cómo revertir la distorsión y aumentar la precisión del reconocimiento del producto.

En primer lugar, considere qué es la distorsión.

La etiqueta rectangular, cuando está pegada al cilindro, tiene la forma característica de un barril (b en el diagrama de arriba). La curva ABC en este caso, en una aproximación bastante buena, es una elipse, porque vemos un círculo (sección del cilindro) en ángulo. Las muchas líneas horizontales de la etiqueta también se transforman en muchas elipses en la fotografía.
Lo más interesante es que para expandir la etiqueta, solo especifique 6 marcadores (ABCDEF):

Y usándolos, construya una cuadrícula de superficie completa:

Al tener una cuadrícula de superficie, podemos expandir cada mosaico por separado y obtener la superficie original:
El código de la biblioteca está disponible en el github . La conveniencia de este método es que los parámetros de entrada para la transformación inversa son características definidas visualmente de la etiqueta (ángulos y puntos superiores e inferiores), lo que le permite automatizar completamente el proceso.
La siguiente parte trata sobre la definición de marcadores. El código de trabajo solo está parcialmente disponible en la
rama del github , como Una solución realmente funcional está cubierta por los hacks y el chamanismo, por lo que la conciencia simplemente no permite que ese estaño se cargue en un github.
Etapa uno: convierta la imagen a blanco y negro.
Luego debe obtener los contornos de la botella con la etiqueta. Para hacer esto, usamos la
transformación sobel . En resumen, este filtro primero difumina la imagen y luego la resta del original. Como resultado, incluso las áreas permanecen oscuras y los bordes (cambios) permanecen claros.

Lo siguiente que debe hacer es identificar las dos líneas verticales más notables, que, si tiene suerte, son los bordes de la botella. En este caso, esto es cierto, pero si fotografía una botella junto a otras botellas, entonces este ya no es el caso.
Para determinar estas líneas, use
la transformación Hough . La esencia de la técnica es que tomamos muchas líneas que atraviesan toda la pantalla y consideramos el valor promedio de los píxeles (por ejemplo, tomamos líneas que van desde la parte superior de la imagen hasta la parte inferior). Transferimos estos valores al nuevo plano de coordenadas y obtenemos algo así como un mapa de calor. En este mapa de calor, estamos buscando dos extremos: son las líneas laterales.
El siguiente diagrama muestra cómo la línea izquierda va a un punto en el nuevo plano de coordenadas:

Con las elipses un poco más complicadas, pero sabiendo que la transformación de Hough se puede aplicar a cualquier curva matemáticamente definida, usaremos este método nuevamente, pero esta vez buscaremos muchas curvas elípticas.
Pero primero debe llevar el problema a una forma bidimensional. Sabiendo que la botella es centralmente simétrica, tomamos el eje central para la coordenada Y, y un lado para X. Para los valores en el nuevo plano de coordenadas, tomamos muchas elipses construidas entre el eje central y el lado. Esto es posible debido al hecho de que un punto arbitrario en el lado y el eje central tienen solo un método de conexión. Quizás esto no sea muy obvio a primera vista, pero es mucho más fácil de entender si recurrimos a la fórmula paramétrica de la elipse:
x = a * cos (t)
y = b * sin (t)

Exactamente de la misma manera, encontramos los dos extremos buscados que definen dos elipses de etiqueta (curvas AB, FE). Ahora que tenemos todos los parámetros de etiqueta necesarios (curvas laterales, así como elipses superior e inferior), podemos aplicar el algoritmo desde la primera parte del artículo y realizar la transformación inversa.
Lo que se puede mejorar. En primer lugar, el algoritmo no tiene en cuenta la distorsión de la perspectiva de la propia elipse, como resultado, los fragmentos laterales de la etiqueta se estiran un poco más de lo que deberían. Para hacer una corrección, debe conocer el ángulo de visión real de la cámara, o al menos usar el más típico para el teléfono (puede elegir empíricamente).
En segundo lugar, la transformación de Hough funciona bastante inestable en condiciones difíciles, por ejemplo, cuando las botellas adyacentes caen en el marco y los bordes de la botella de interés pueden no detectarse correctamente.
En tercer lugar, si la etiqueta no tiene forma rectangular (por ejemplo, elíptica), los marcadores se detectarán incorrectamente y la transformación solo distorsionará la imagen con más fuerza.
En la práctica, es mucho más interesante usar una red neuronal para identificar marcadores, porque se puede entrenar usando ejemplos complejos para que, como mínimo, el algoritmo no realice la transformación si no se pueden determinar los marcadores. Pero hasta ahora no he tratado de usar neurona para esta tarea, por lo que quizás este sea el tema de un artículo separado :)