Dans notre application, il y a une fonctionnalité, comme le
fils de Vivino, la
petite amie de ma mère - la définition du vin à partir d'une photographie. Sous le capot - l'utilisation de services tiers, Tineye - pour déterminer l'étiquette la plus appropriée, Google Vision - pour lire le texte dessus. Ce dernier est nécessaire pour clarifier le bon produit, car la recherche d'images ne prend pas en compte l'importance de certaines régions, en règle générale - il s'agit d'informations textuelles - l'année et le type de vin.
Cependant, la précision des deux services est sensiblement réduite en raison du fait que l'étiquette est déformée par une surface cylindrique.
Cela est particulièrement visible avec Google Vision - tout texte en dehors de la partie centrale de l'étiquette est pratiquement illisible, bien qu'une personne le reconnaisse facilement. Dans cet article, je décrirai comment inverser la distorsion et augmenter la précision de la reconnaissance des produits.

Tout d'abord, considérez ce qu'est la distorsion.

L'étiquette rectangulaire, collée au cylindre, a la forme caractéristique d'un baril (b dans le schéma ci-dessus). La courbe ABC dans ce cas, dans une assez bonne approximation, est une ellipse, car nous voyons un cercle (section de cylindre) à un angle. Les nombreuses lignes horizontales de l'étiquette se transforment également en de nombreuses ellipses sur la photo.
La chose la plus intéressante est que pour développer l'étiquette, spécifiez simplement 6 marqueurs (ABCDEF):

Et en les utilisant, construisez une grille de surface complète:

Ayant une grille de surface, nous pouvons agrandir chaque tuile séparément et obtenir la surface d'origine:
Le code de la bibliothèque est disponible sur le github . La commodité de cette méthode est que les paramètres d'entrée pour la transformation inverse sont des caractéristiques visuellement définies de l'étiquette (angles et points supérieurs et inférieurs), ce qui vous permet d'automatiser complètement le processus.
La partie suivante concerne la définition des marqueurs. Le code de travail n'est que partiellement disponible dans la
branche sur le github , comme une solution vraiment fonctionnelle est couverte par des hacks et du chamanisme, donc la conscience ne permet tout simplement pas de télécharger une telle boîte sur un github.
Première étape - convertissez l'image en noir et blanc.
Ensuite, vous devez obtenir les contours de la bouteille avec l'étiquette. Pour ce faire, nous utilisons la
transformation sobel . En bref, ce filtre brouille d'abord l'image, puis la soustrait de l'original. Par conséquent, même les zones restent sombres et les bords (changements) restent clairs.

La prochaine chose à faire est d'identifier les deux lignes verticales les plus visibles, qui, si vous êtes chanceux, sont les bords de la bouteille. Dans ce cas, c'est vrai, mais si vous photographiez une bouteille à côté d'autres bouteilles, ce n'est plus le cas.
Pour déterminer ces lignes, utilisez
la transformation Hough . L'essence de la technique est que nous prenons beaucoup de lignes qui traversent tout l'écran et considérons la valeur moyenne des pixels (par exemple, nous prenons des lignes qui vont du haut de l'image vers le bas). Nous transférons ces valeurs dans le nouveau plan de coordonnées et obtenons quelque chose comme une carte thermique. Sur cette carte thermique, nous recherchons deux extrema - ce sont les lignes latérales.
Le diagramme ci-dessous montre comment la ligne gauche va à un point sur le nouveau plan de coordonnées:

Avec des ellipses un peu plus compliquées, mais sachant que la transformée de Hough peut être appliquée à toutes les courbes définies mathématiquement, nous utiliserons à nouveau cette méthode, mais cette fois, nous chercherons beaucoup de courbes elliptiques.
Mais vous devez d'abord amener le problème sous une forme bidimensionnelle. Sachant que la bouteille est symétrique au centre, nous prenons l'axe central pour la coordonnée Y et un côté pour X. Pour les valeurs sur le nouveau plan de coordonnées, nous prenons beaucoup d'ellipses construites entre l'axe central et le côté. Cela est possible du fait qu'un point arbitraire sur le côté et l'axe central n'ont qu'une seule méthode de connexion. Ce n'est peut-être pas très évident à première vue, mais il est beaucoup plus facile de comprendre si nous nous tournons vers la formule paramétrique de l'ellipse:
x = a * cos (t)
y = b * sin (t)

Exactement de la même manière, on retrouve les deux extremums recherchés qui définissent deux ellipses d'étiquettes (courbes AB, FE). Maintenant que nous avons tous les paramètres d'étiquette nécessaires (courbes latérales, ainsi que les ellipses supérieures et inférieures), nous pouvons appliquer l'algorithme de la première partie de l'article et effectuer la transformation inverse.
Ce qui peut être amélioré. Premièrement, l'algorithme ne prend pas en compte la distorsion de la perspective de l'ellipse elle-même, par conséquent, les fragments latéraux de l'étiquette sont un peu plus étirés qu'ils ne le devraient. Pour effectuer une correction, vous devez connaître l'angle de vision réel de l'appareil photo, ou au moins utiliser le plus typique pour le téléphone (vous pouvez choisir empiriquement).
Deuxièmement, la transformation de Hough fonctionne plutôt instable dans des conditions difficiles - par exemple, lorsque des bouteilles adjacentes tombent dans le cadre et que les bords de la bouteille d'intérêt peuvent ne pas être détectés correctement.
Troisièmement, si l'étiquette n'est pas de forme rectangulaire (par exemple elliptique), les marqueurs seront détectés de manière incorrecte et la transformation ne fera que déformer l'image plus fortement.
En pratique, il est beaucoup plus intéressant d’utiliser un réseau de neurones pour identifier les marqueurs, car il peut être formé à l'aide d'exemples complexes afin que, au minimum, l'algorithme n'effectue pas de transformation si les marqueurs ne peuvent être déterminés. Mais jusqu'à présent, je n'ai pas essayé d'utiliser les neurones pour cette tâche, alors ce sera peut-être le sujet d'un article séparé :)